viernes, 26 de abril de 2013

ORA-14223

Probé este ejemplo en Oracle 11.2.0.2.7. Se puede crear una tabla con creación diferida de la manera siguiente:

SQL> conn andrew/reid
Conectado.
SQL> create table blah (col1 number)
  2  segment creation deferred
  3  /

Tabla creada.

SQL>

Pero algunos usuarios, por ejemplo SYS, no están permitidos hacerlo:

SQL> conn / as sysdba
Conectado.
SQL> show user
USER es "SYS"
SQL> l
  1  create table blah (col1 number)
  2* segment creation deferred
SQL> /
create table blah (col1 number)
*
ERROR en linea 1:
ORA-14223: No esta soportada la creacion de segmentos diferida para esta tabla

SQL>

En inglés / in English

viernes, 19 de abril de 2013

SELECT ... INTO

Leí este ejemplo aquí Luego decidí traducirlo para los hispanohablantes. Tanel Poder buscaba un error en una fila de SQL. Entonces se dio cuenta que había escrito SELECT…INTO en SQL*Plus. No funcionó pero no le dio ningún error: 

SQL> var tanel_poder varchar2(10)
SQL> select dummy into :tanel_poder from dual
  2  /

D
-
X

SQL> 

Tras hacerlo, la variable estaba vacía: 

SQL> print tanel_poder

TANEL_PODER
--------------------------------


SQL> 

Repitió la petición en PL/SQL y funcionó: 

SQL> begin
  2  select dummy into :tanel_poder from dual;
  3  end;
  4  /

Procedimiento PL/SQL terminado correctamente.

SQL>

Esta vez, el contenido de DUAL estaba en la variable TANEL_PODER:

SQL> print tanel_poder

TANEL_PODER
--------------------------------
X

SQL>

jueves, 11 de abril de 2013

ORA-01733

Aquí está un ejemplo sobre el error ORA-01733. Para empezar, necesitamos una tabla con datos: 

SQL> create table mi_tabla
  2  (mi_nombre varchar2(10))
  3  /

Tabla creada.

SQL> insert into mi_tabla
  2  values('Carlos')
  3  /

1 fila creada.

SQL>

Luego debemos crear una vista de la tabla. La vista tiene que incluir una columna virtual, es decir una columna que no corresponde a ningunos datos en la tabla. Decidí añadir una edad de 21 años a cada fila. No hay columna en la tabla para tomar nota de la edad. Así puse 21 en la vista y lo llamé edad. No es buena idea hacer éste con sus propias bases de datos. Estoy haciendolo simplemente para explicar el error:

SQL> create view mi_vista
  2  as select mi_nombre, 21 edad
  3  from mi_tabla
  4  /

Vista creada.

SQL> select * from mi_vista
  2  /

MI_NOMBRE        EDAD
---------- ----------
Carlos             21

SQL>

Se puede emplear la vista para poner al día mi_nombre porque la columna en la vista corresponde a la columna en la tabla: 

SQL> update mi_vista
  2  set mi_nombre = 'Manuel'
  3  where mi_nombre = 'Carlos'
  4  /

1 fila actualizada.

SQL>

Pero si Vd intenta actualizar edad, Oracle le da el error ORA-01733: 

SQL> update mi_vista
  2  set edad = edad + 1
  3  /
set edad = edad + 1
* ERROR en linea 2: 
ORA-01733: columna virtual no permitida aqui

SQL>

Si Vd quiere cambiar la edad, tiene que borrar la vista y recrearla con el nuevo valor.

lunes, 8 de abril de 2013

ORA-02429

Leí este ejemplo aquí Luego decidí traducirlo para los hispanohablantes. Lo probé en Oracle 11.2.0.2.7. Es muy fácil crear y borrar un índice normal: 

SQL> conn andrew/reid
Connected.
SQL> alter session set nls_language = 'SPANISH'
  2  /

Sesion modificada.

SQL> create table andrews_table
  2  (andrews_column number)
  3  /

Tabla creada.

SQL> create index andrews_index on
  2  andrews_table(andrews_column)
  3  /

Indice creado.

SQL> drop index andrews_index
  2  /

Indice borrado.

SQL>

Pero si un índice sea creado automáticamente para ser empleado con un constraint, no se puede borrarlo. Para empezar, ponemos un constraint en nuestra tabla: 

SQL> alter table andrews_table
  2  add constraint andrews_constraint
  3  unique(andrews_column)
  4  /

Tabla modificada.

SQL>

Se puede ver el constraint en user_tables: 

SQL> select constraint_name
  2  from user_constraints
  3  where table_name = 'ANDREWS_TABLE'
  4  /

CONSTRAINT_NAME
------------------------------
ANDREWS_CONSTRAINT

SQL>

El constraint tiene un índice con el mismo nombre: 

SQL> select index_name
  2  from user_indexes
  3  where table_name = 'ANDREWS_TABLE'
  4  /

INDEX_NAME
------------------------------
ANDREWS_CONSTRAINT

SQL>

Pero no es posible borrarlo: 

SQL> drop index andrews_constraint
  2  /
drop index andrews_constraint
           *
ERROR en linea 1:
ORA-02429: no se puede borrar el indice utilizado para
aplicar la clave unica/primaria

SQL>

Para borrar el índice, es necesario borrar el propio constraint: 

SQL> alter table andrews_table
  2  drop constraint andrews_constraint
  3  /

Tabla modificada.

SQL>

Luego el  índice desaparece automáticamente y no es necesario borrarlo: 

SQL> drop index andrews_constraint
  2  /
drop index andrews_constraint
           *
ERROR en linea 1: ORA-01418: el indice especificado no existe

SQL>

martes, 2 de abril de 2013

dbverify en Modo Paralelo

Encontré este ejemplo, escrito por Uwe Hesse, aquí Entonces decidí traducirlo para los hispanohablantes. Ahora con dbverify se puede dividir una fila y procesar las partes individuales simultáneamente. Antes de empezar hay que saber cuantos bloques tiene la fila: 

Oracle 11.1 > sqlplus /

SQL*Plus: Release 11.1.0.6.0 - Production on Mon Nov 26 17:49:33 2012

Copyright (c) 1982, 2007, Oracle. All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> col file_name format a40
SQL> select file_name, blocks
  2  from dba_data_files
  3  where tablespace_name = 'SYSTEM';

FILE_NAME                                    BLOCKS
---------------------------------------- ----------
/cisdpt/pqedpt1/pqe_system/system01.dbf      268800

SQL> 

Luego se puede procesar dos (o más de dos) partes de la fila simultáneamente de la manera siguiente. En la primera imagen abajo, me conecté dos veces en el mismo servidor. En la primera conexión procesé los bloques desde 1 hasta 130000. Luego en la segunda conexión procesé los bloques desde 130001 hasta 268800. Lancé el comando date antes y después de cada dbverify para mostrar que los dos dbverify funcionaban simultáneamente. Hay que hacer clic en la imagen dos veces para verla con su tamaño original y enfocarla:

 
Según el propio Uwe, éste apareció en Oracle 11.1 pero según mis pruebas, ya existía en Oracle 10.2, como se puede ver en la imagen siguiente: