Cuando ” no es lo mismo que NULL…

31 Mayo 2007

Todo aquel que trabaja con Oracle sabe que una cadena de longitud 0 se considera NULL ( por cierto, que esto me ha dado más de un quebradero de cabeza trabajando con java y Oracle, pero eso es otra historia…)

Así pues, en teoría, en PL/SQL es lo mismo declarar una cadena como como ” o como NULL. ¿Sí? Veamos:

carlos@bd01.xxxxxxxx> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for Solaris: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

carlos@bd01.xxxxxxxx> DECLARE
  2          v_cadena VARCHAR2(10);
  3  BEGIN
  4
  5     DBMS_OUTPUT.PUT_LINE('Sin inicializar. v_cadena: *'||
  6                            NVL(v_cadena,'NULL')||'*');
  7     DBMS_OUTPUT.PUT_LINE(' ');
  8
  9     v_cadena := NULL;
 10     DBMS_OUTPUT.PUT_LINE('Asignando NULL. v_cadena: *'||
 11                           NVL(v_cadena,'NULL')||'*');
 12     DBMS_OUTPUT.PUT_LINE(' ');
 13
 14     v_cadena := '';
 15     DBMS_OUTPUT.PUT_LINE('Asignando ''''. v_cadena: *'||
 16                           NVL(v_cadena,'NULL')||'*');
 17     DBMS_OUTPUT.PUT_LINE(' ');
 18  END;
 19  /
Sin inicializar. v_cadena: *NULL*
Asignando NULL. v_cadena: *NULL*
Asignando ''. v_cadena: *NULL*

Procedimiento PL/SQL terminado correctamente.

Pues parece que sí. Pero…

carlos@bd01.xxxxxxxx> DECLARE
  2          v_cadena CHAR(10);
  3  BEGIN
  4
  5     DBMS_OUTPUT.PUT_LINE('Sin inicializar. v_cadena: *'||
  6                           NVL(v_cadena,'NULL')||'*');
  7     DBMS_OUTPUT.PUT_LINE(' ');
  8
  9     v_cadena := NULL;
 10     DBMS_OUTPUT.PUT_LINE('Asignando NULL. v_cadena: *'||
 11                           NVL(v_cadena,'NULL')||'*');
 12     DBMS_OUTPUT.PUT_LINE(' ');
 13
 14     v_cadena := '';
 15     DBMS_OUTPUT.PUT_LINE('Asignando ''''. v_cadena: *'||
 16                           NVL(v_cadena,'NULL')||'*');
 17     DBMS_OUTPUT.PUT_LINE(' ');
 18  END;
 19  /
Sin inicializar. v_cadena: *NULL*
Asignando NULL. v_cadena: *NULL*
Asignando ''. v_cadena: *          *

Procedimiento PL/SQL terminado correctamente.

¡Pues resulta que no! Al menos no en todos los casos. Las asignaciones de cadenas vacías (”) a variables CHAR son rellenadas a blancos hasta la longitud declarada de la cadena, por lo que no es lo mismo asignar ” que asignar NULL. Mientras que para cadenas VARCHAR2 la asignasión de ” o NULL sí es equivalente, dando como resultado el mismo NULL.

Saludos.

Carlos.


OpenSuSE 10.2 (4)

24 Mayo 2007

Empiezo a estar un poco hasta las narices de esta distribución.

La última: YaST/YaST2 no me deja añadir ni los repositorios más básicos. No hay manera de pasar de “Unknown source type for…”

"Unknown source type for http://download.opensuse.org/distribution/10.2/repo/oss/suse"

Y este es sólo un ejemplo. He probado infinidad de ellos (casi todos los que aparecen en opensuse.org) siempre con el mismo (y frustrante) resultado de arriba.

Saludos.

Carlos.


¡Un año ya!

23 Mayo 2007

Hoy hace exactamente un año que empecé este blog lleno de dudas acerca de su utilidad y pertinencia.

Durante estos 365 días han pasado muchas cosas: nuevos trabajos, nuevos sistemas operativos, nuevas versiones de Oracle, ¡incluso un nuevo hijo!

Pero lo más agradable es que he despejado las dudas que tenía al comenzar: 15000 visitas desde todo el mundo (una gran parte desde Hispanoamérica) hacen que mi idea acerca de un ‘blog’ de Oracle (y otras cosas) en español no sea -aparentemente- tan inútil como me temí en un principio.

Para los habituales: ¡Feliz cumpleaños!

Para los ocasionales: Aquí estamos y pensamos seguir.

Saludos.

Carlos.


OpenSuSE 10.2 (3)

19 Mayo 2007

Bueno, pues ya he conseguido instalar la aceleración 3D de la ATI. La cosa no ha sido fácil, porque una de las cosas que tiene Linux es una cierta tendencia a los ‘aspectos esotéricos’: tras bajarme el driver de la web de ATI (http://ati.amd.com) intenté por tres veces la instalación siguiendo paso a paso las instrucciones. Las dos primeras fallaron. La tercera (no sé por qué, ya que hice exactamente lo mismo que en las otras dos) por fin me dejó instalado el 3D.

Lo que parece ser una misión imposible es el asunto del micrófono. No consigo que funcione de ninguna de las maneras. Lo he probado todo (como ya hice con Ubuntu) sin ningún resultado. He comenzado a sospechar que la tarjeta de sonido pueda estar estropeada. El caso es que sigo sin poder utilizar Skype en Linux.

Seguiremos informando…

Saludos.

Carlos.


El Bicho Número 2

11 Mayo 2007

El día 11 de mayo de 2007 ha llegado a nuestras vidas el Bicho Número 2. Se presentó además con la sorpresa (incluso para el ginecólogo que hizo las ecografías) de tener el sexo opuesto al esperado.

El Bicho Número 2

Todas las conversaciones, negociaciones y acuerdos acerca del nombre que iba a tener no sirven, pues, para nada.

Saludos (de un orgulloso papá).

Carlos.


/*+ APPEND */ pros y contras.

10 Mayo 2007

Recientemente ha caído en mis manos un código PL/SQL (en forma de ‘package’) en el cual se utilizaban profusamente ‘hints’ /*+ APPEND */ en varias partes del mismo, seguidos -claro- de los correspondientes ‘COMMIT’. Esto (hacer ‘commit’ en medio de procesos), dentro de un paquete/procedimiento es algo que, de entrada, repele mis más primarios instintos. Como quiera que pregunté al programador en cuestión y me dijo que lo hacía ‘por rendimiento’, llegué a la conclusión de que muchas veces ciertos programadores ‘oyen campanas y no saben dónde’. Él había oído que así los ‘INSERTS’ corren más, pero no conocía todos los aspectos que, en un entorno real (Base de Datos OLTP con múltiples usuarios), pueden provocar efectos muy perjudiciales.

Vamos a intentar ver las peculiaridades de este ‘hint’ para poder decidir cuando utilizarlo y cuando no.

Para empezar, hay que tener claro qué hace exactamente este ‘hint’: /*+ APPEND */ inserta los datos en los segmentos utilizando bloques nuevos por encima del HWM (High WaterMark). Esto hace que se evite la utilización de segmentos de ‘ROLLBACK/UNDO’, ya que no hay posibidad de que otro usuario registre actividad sobre los mismos. A esto se le llama ‘DIRECT PATH‘. Aquí es (sobre todo si se suma a otros aspectos que pueden también eliminar REDO, como el uso de ‘NOLOGGING’) donde se consigue una mejora en el rendimiento. Esto viene de perlas en el caso de cargas masivas de tablas.

Pero ¿qué pasa si lo utilizamos en un entorno multiusuario (como nuestro amigo el programador lo hacía en mitad de la utilización normal de una base de datos OLTP)?

Como siempre, crearemos una de nuestras tablas de pruebas:

carlosal@db01.xxxxxx> SELECT * FROM V$VERSION
  2  /

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for Solaris: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

carlosal@db01.xxxxxx> CREATE TABLE PRUEBA07 AS SELECT *
  2  FROM DBA_OBJECTS WHERE 1=0
  3  /

Tabla creada.

carlosal@db01.xxxxxx>

Ahora insertamos filas e inmediatamente intentamos acceder a la tabla (contando cuantas filas tiene)

Primero sin ‘hint’:

carlosal@db01.xxxxxx> INSERT INTO PRUEBA07 SELECT * FROM DBA_OBJECTS
  2  /

11174 filas creadas.

carlosal@db01.xxxxxx> SELECT COUNT('X') FROM PRUEBA07
  2  /

COUNT('X')
----------
     11174

carlosal@db01.xxxxxx> ROLLBACK
  2  /

Rollback terminado.

carlosal@db01.xxxxxx>

Ningún problema. Vamos ahora a utilizar el ‘hint’:

carlosal@db01.xxxxxx> INSERT /*+ APPEND */ INTO PRUEBA07
  2  SELECT * FROM DBA_OBJECTS
  3  /

11174 filas creadas.

carlosal@db01.xxxxxx> SELECT COUNT('X') FROM PRUEBA07
  2  /
SELECT COUNT('X') FROM PRUEBA07
                       *
ERROR en línea 1:
ORA-12838: cannot read/modify an object after modifying it in parallel

carlosal@db01.xxxxxx> COMMIT
  2  /

Confirmación terminada.

carlosal@db01.xxxxxx> SELECT COUNT('X') FROM PRUEBA07
  2  /

COUNT('X')
----------
     11174

¡Ups! Cuando intentamos acceder a la tabla ANTES DE HACER UN COMMIT, nos aparece el ORA-12838. Hasta que no hacemos un ‘commit’ las cosas no funcionan como esperamos.

La explicación es que al utilizar el ‘hint’ y ’saltarnos’ en ROLLBACK/UNDO estamos imposibilitando el famoso READ COMMITED, por el cual veremos los datos de nuestra transacción en modo aislado. Cuando hacemos el ‘commit’ volvemos al ‘estado normal de las cosas’ y sólo entonces podemos ver que tenemos 11174 filas en la tabla. Esto explica por qué nuestro programador intercalaba ‘commits’ dentro de su procedimiento. Si no, no tendría visibilidad sobre los datos insertados.

Este es uno de los aspectos ‘peliagudos’ del uso de /*+ APPEND */, pero hay más.

Supongamos nuevas inserciones sobre una tabla existente sobre la cual se registra activdad de otros usuarios. En un insert ‘normal’ no habrá problemas de concurrencias. Si hacemos un ‘insert’ masivo mientras otros usuarios modifican datos, la base de datos lo asume ‘como si nada’:

Sesión 1:

carlosal@db01.xxxxxx> INSERT INTO PRUEBA07 SELECT * FROM DBA_OBJECTS
  2  /

11174 filas creadas.

carlosal@db01.xxxxxx>

Nótese que no hemos hecho el ‘commit’, por lo que la transacción está activa.

En la sesión 2:

carlosal@db01.xxxxxx> SELECT MIN (OBJECT_ID), MAX(OBJECT_ID) FROM PRUEBA07
  2  /

MIN(OBJECT_ID) MAX(OBJECT_ID)
-------------- --------------
             2          44228

carlosal@db01.xxxxxx> UPDATE PRUEBA07
  2  SET OBJECT_ID = 44226 WHERE OBJECT_ID =2
  3  /

1 fila actualizada.

carlosal@db01.xxxxxx> ROLLBACK
  2  /

Rollback terminado.

carlosal@db01.xxxxxx>

La sesión 2 puede funcionar sin novedad. Pero si la sesión 1 utiliza el famoso ‘hint’ tenemos que:

Sesión 1:

carlosal@db01.xxxxxx> INSERT /*+ APPEND */ INTO PRUEBA07
  2  SELECT * FROM DBA_OBJECTS
  3  /

11174 filas creadas.

carlosal@db01.xxxxxx>

Otra vez hemos dejado la transacción pendiente.

Sesión 2:

carlosal@db01.xxxxxx> UPDATE PRUEBA07 SET OBJECT_ID = 44226
  2  WHERE OBJECT_ID =2
  3  /
_

Ahora la sesión 2 se queda esperando. La sesión 1 HA BLOQUEADO LA TABLA para poder efectuar su ‘insert’ en ‘DIRECT PATH’, y hasta que no concluya su transacción, la tabla permanecerá bloqueada.

Ni que decir tiene que en un entorno multiusuario esto es el típico ‘peor caso posible’.

En resumen:

Yo no soy muy partidario de los ‘hints’ en general (aunque siempre hay excepciones, claro), pero este ‘hint’ en particular puede ser especialmente dañino. /*+ APPEND */ debería usarse casi exclusivamente en herramientas -’scripts’- de carga masiva de datos y sólo bajo determinadas circunstancias (principalmente cuando tenemos un entorno ‘aislado’ en el cual no hay más usuarios accediendo a la tabla sobre la que estamos insertando datos).
Por otra parte, bien utilizado en esos casos, su uso puede dar rendimientos espectaculares.

Pero siempre -siempre- sabiendo exactamente qué estamos haciendo. Y por qué.

Saludos.

Carlos.


¡Oracle 10.2.0.3 para Windows Vista!

8 Mayo 2007

¡Ya se puede descargar la versión de Oracle 10.2.0.3 para Windows Vista!

Esta es una versión que de momento no pienso instalar…

Saludos.

Carlos.


OpenSuSE 10.2 (2)

6 Mayo 2007

Bueno, pues parece que las cosas van mejorando. No sé porqué SuSE veía la máquina Windows como un alias de la propia máquina Linux. De ahí el follón de IP’s (debí de meter la pata en algún punto de la instalación).

Tras eliminar la ’segunda’ tarjeta de red (misma MAC, pero con nombre e IP de la máquina Windows) y volver a configurar el Proxy, tengo conectividad por la LAN y he podido conectar con la internet (de hecho, este artículo ya lo estoy escribiendo en OpenSuSE…)

Tambien he conseguido que el samba funcione, con lo que veo las carpetas compartidas en Windows.

Me queda aun un largo camino: configurar la aceleración gráfica de la ATI, seguir investigando qué demonios le pasa a la tarjeta de sonido (¡otra vez!) Una cosa curiosa es que realplayer puede leer directamente los mp3 que tengo en una carpeta compartida en Windows (En Ubuntu no podía hacerlo con Mplayer), pero aunque parece que realplayer funciona, no sale ni una triste nota de la canción -que según él está sonando- ni por los altavoces ni por los cascos.

Pero bueno, se puede decir que este domingo por la mañana ha sido mucho más productivo que la tarde de sábado de ayer (al menos en lo referente a solucionar los problemas).

Por otra parte, el aspecto general de la distribución es bastante bueno. El entorno (KDE) es un poco diferente a lo que estoy acostumbrado, pero todo se andará.

Seguiremos buceando en la documentación (sobre todo en el YaST) para ver hasta dónde podemos llegar con esta distribución.

Saludos.

Carlos.


OpenSuSE 10.2

5 Mayo 2007

Harto de no poder utilizar el micrófono en Ubuntu, me he hecho con una copia de OpenSuSE 10.2 esperando por fin poder utilizar skype sin problemas.

Pero las primeras sensaciones no son muy buenas…

Tras reparticionar el disco duro, he optado por una instalación dual (con grub), para así preservar todo el software que tengo instalado en Ubuntu (¡Oracle 10 incluido!).

Así que me he pasado la tarde del sábado instalando el OpenSuSE 10.2 (a la vez que jugaba con El Bicho en la máquina Windows al ‘pinball’ y otros juegos para niños).

He de decir que no tengo experiencia en SuSE: sólo un poco con el KDE de RedHat…

Pero he aquí que las cosas no han sido ni mucho menos tan fáciles como se anuncian (“el S.O. más parecido a Windows por su facilidad de instalación y uso”).

Entre otras cosas:

  • No consigo ver las carpetas de la máquina Windows como hago desde Ubuntu (samba se niega a ver las carpetas compartidas Windows). Aunque sí consigo hacer ‘ping’ y ‘traceroute’ a esta máquina. Curiosamente, desde Windows no puedo hacer ‘ping’ a la máquina Linux cuando he arrancado SuSE, pero sí cuando he arrancado Ubuntu (¿?).
  • No consigo una conexión a internet a través del ‘proxy’ que tengo en Windows como tan fácilmente conseguí con Ubuntu (‘el proxy rechaza la conexión‘ es el mensaje que consigo una y otra vez).
  • SuSE ha reconocido la tarjeta de sonido, pero no sólo el micrófono no funciona: no sale ni un maldito sonido por los altavoces (como se suele decir: he salido de Málaga para llegar a Malagón)
  • Por no saber, no sé ni cómo se abre el DVD…

A pelearse tocan… (otra vez).

Saludos.

Carlos.