Vivo y trabajo cerca de una instalación de Microsoft. Como tal, muchos de nuestros empleados actuales son ex empleados de Microsoft que provienen de un entorno de SQL Server. SQL Server le permite crear una tabla con una columna IDENTIDAD. Oracle 12c ahora le permite hacer lo mismo. Esto debería ayudar a aquellos que están haciendo la transición de SQL Server a Oracle. También permite que una empresa transfiera más fácilmente una aplicación de SQL Server, o cualquier otra base de datos que permita la columna IDENTIDAD, a Oracle.
Primero crearé una tabla con la columna IDENTIDAD y la completaré con algunas filas de datos.
SQL> crear tabla test_tab (2 id NÚMERO GENERADO POR DEFECTO EN NULL COMO IDENTIDAD, 3 val VARCHAR2(20));Tabla creada.SQL> insertar en test_tab (val) valores ('mi primera fila');1 fila created.SQL> insert into test_tab (val) valores ('mi segunda fila'); 1 fila created.SQL> commit;Commit complete.
Tenga en cuenta que no inserté ningún valor en la columna ID. Ahora consultemos la tabla.
SQL> select * from test_tab;ID VAL---------- --------------------1 mi primera fila2 mi segunda fila
Como puede ver, mis valores de ID se han agregado como era de esperar. En la creación de mi tabla, definí esta columna IDENTIDAD con: GENERATED BY DEFAULT ON NULL
La cláusula BY DEFAULT significa que Oracle asignará automáticamente el siguiente valor en la secuencia si lo omite en su instrucción INSERT. Si lo incluye, Oracle utilizará su valor especificado. Considere esto:
SQL> inserte en los valores de test_tab (4, 'ID especificado =4'); 1 fila creada.SQL> commit;Commit complete.SQL> select * from test_tab; ID VAL---------- -------------------- 1 mi primera fila 2 mi segunda fila 4 ID especificado=4
Como puede ver, porque indiqué explícitamente ID=4 y Oracle dejó pasar ese valor. ¿Qué sucede cuando intento insertar el siguiente valor, que debería ser 3?
SQL> inserte en test_tab (val) valores ('mi fila después de ID=4'); 1 fila creada.SQL> commit;Commit complete.SQL> select * from test_tab; ID VAL--------------- -------------------- 1 mi primera fila 2 mi segunda fila 4 ID especificado=4 3 mi fila después de ID =4Lo anterior funcionó como esperaba. Se utilizó el siguiente valor de ID disponible. Pero, ¿la próxima inserción usará '4' o '5'?
SQL> insertar en los valores test_tab (val) ('mi quinta fila'); 1 fila creada.SQL> confirmar; Confirmar completa.SQL> seleccionar * de ficha_prueba; ID VAL--------------- -------------------- 1 mi primera fila 2 mi segunda fila 4 ID especificado=4 3 mi fila después de ID =4 4 mi quinta fila¡UH oh! Se permitió el valor duplicado. Habría esperado que se creara una restricción de clave principal para hacer cumplir el concepto de un valor de "identidad", pero eso no sucede. ¿Qué restricciones existen?
SQL> seleccione nombre_restricción,tipo_restricción,nombre_tabla,condición_búsqueda de restricciones_usuario;NOMBRE_RESTRICCIÓN C NOMBRE_TABLA--------------------------- --- - ------------------------------CONDICIÓN_DE_BÚSQUEDA--------------- -------------------------------------------------- ---------------SYS_C004978 C TEST_TAB"ID" NO ES NULOEntonces, la única restricción es una restricción de verificación NOT NULL. Ahora eliminemos la última fila y agreguemos una restricción PK.
SQL> delete from test_tab where val='my quinta fila';1 fila eliminada.SQL> commit;Commit complete.SQL> alter table test_tab agregar restricción test_tab_pk clave primaria (id);Tabla alterada.Ahora me aseguraré de tener algunos datos para probar. 6, 'establecer explícitamente id=6'); 1 fila creada. SQL> confirmar; Confirmar completa. SQL> seleccionar * de test_tab; ID VAL--------------- -------------------- 1 mi primera fila 2 mi segunda fila 4 ID especificado=4 3 mi fila después de ID =4 5 después de la restricción de pk 6 establece explícitamente id=66 filas seleccionadas. Entonces agregué explícitamente ID =6. Si esto es como cuando agregué explícitamente ID=4, mi próxima inserción intentará usar ID=6 y con la restricción PK en su lugar, se lanzará una excepción.
SQL> insert into test_tab (val) valores (' después de ID=6');insertar en test_tab (val) valores ('después de ID=6')*ERROR en la línea 1:ORA-00001:restricción única (PEASLAND.TEST_TAB_PK) violadaEntonces, la moraleja de la historia es que si usa ON DEFAULT, esté preparado para manejar colisiones de valores de identidad. El valor predeterminado es SIEMPRE en lugar de EN DEFECTO. Con SIEMPRE, Oracle siempre utilizará el generador de números de secuencia. Si intenta especificar un valor de identificación, se producirá una excepción.
SQL> crear tabla test_tab2 (número de identificación generado siempre como identidad, val varchar2 (20)); tabla creada. SQL> insertar en test_tab2 (id, val) valores (1, 'primera fila'); insertar en test_tab2 (id, val) valores (1, 'primera fila') *ERROR en la línea 1:ORA-32795:no se puede insertar en una columna de identidad siempre generadaLa vista *_TAB_COLUMNS puede mostrarle qué columnas de una tabla son columnas IDENTITY.
SQL> select column_name,identity_column from user_tab_columns where table_name='TEST_TAB';COLUMN_NAME IDE-------------- - ---ID YESVAL NOSi usa la columna IDENTIDAD en sus tablas, tenga cuidado de probar para asegurarse de que comprende que funciona correctamente para su aplicación. Me sorprendió que no se incluyera automáticamente una restricción PK o ÚNICA, lo que me permitió agregar un valor duplicado.