SQLLoader DIRECT=TRUE y INDEX UNIQUE (caso practico)

Problema:  
Luego de una carga de datos realizada con sqlloader DIRECT=TRUE los índices se invalidan y muestran  estatus "UNUSABLE".


Caso de Prueba:
Creamos una tabla con un índice que no permita valores duplicados;

SQL> create table hr.test_loader
(id number,
field01 varchar2(12)) tablespace USERS;

Table created.


SQL> create unique index hr.pk_test_loader on hr.test_loader(id) tablespace USERS;

Index created.


Verificamos el estatus del índice.

SQL> select status from dba_indexes where index_name='PK_TEST_LOADER';

STATUS
--------
VALID



Realizamos la primera carga de datos con el SQLLOADER.

sqlldr system/********* direct=true control=control.ctl log=mylogfile.log bad=mybadlog.bad data=mydatafile.txt

Archivo:      control.ctl 
load data
infile *
into table hr.test_loader
fields terminated '|'
(id,field01)

Archivo:      mydatafile.txt
1|AAAAA
2|BBBBB
3|CCCCC
4|DDDDD
5|EEEEE



Luego de la carga validamos los registros en la tabla y el estatus del índice y todo esta bien.

SQL> SELECT * FROM hr.test_loader;

        ID FIELD01
---------- ------------
         1 AAAAA
         2 BBBBB
         3 CCCCC
         4 DDDDD
         5 EEEEE

SQL>  select status from dba_indexes where index_name='PK_TEST_LOADER';

STATUS
--------
VALID



Qué pasa si intentamos insertar un valor que ya existe, la restricción del índice único no va permitir que se inserten valores duplicados.

SQL> INSERT INTO  hr.test_loader (ID,FIELD01) VALUES (1,'xxxxx');
INSERT INTO  hr.test_loader (ID,FIELD01) VALUES (1,'xxxxx')
*
ERROR at line 1:
ORA-00001: unique constraint (HR.PK_TEST_LOADER) violated




Que pasa si realizamos otro carga de datos con SQLLOADER DIRECT=TRUE, pero esta vez vamos a insertar un valor que ya existe en el campo con el índice único. El valor 1 en el campo ID ya existe.

 Archivo:     mydatafile.txt
 6|FFFFF
 7|GGGGG
 1|zzzzz



Luego de la carga, validamos los registros en la tabla y el estatus del índice. 


SQL>  SELECT * FROM hr.test_loader;

        ID FIELD01
---------- ------------
         1 AAAAA <--- Este valor fue insertado en la primera carga.
         2 BBBBB
         3 CCCCC
         4 DDDDD
         5 EEEEE
         6 FFFFF
         7 GGGGG
         1 zzzzz <--- Este valor fue insertado y duplicado en la segunda carga.

8 rows selected.

SQL>  select status from dba_indexes where index_name='PK_TEST_LOADER';

STATUS
--------
UNUSABLE


La carga se realizó completa con todos los registros pero ahora el índice cambio a estado UNUSABLE.

Conclusión.

Cuando se realiza una carga con SQLLOADER con la opción DIRECT=TRUE los valores no son llevados a memoria, por ende no son evaluados según la restricción que supone un índice de valores único.

Esto hace que los registros puedan ser insertados obviando la restricción del índice único y convirtiendo el índice como UNUSABLE.


Eini Trujillo

Comments