Tablas de excepciones

Las tablas de excepciones son tablas creadas por el usuario que imitan la definición de las tablas cuya comprobación se especifica utilizando SET INTEGRITY con la opción IMMEDIATE CHECKED. Se utilizan para almacenar copias de las filas que violan las restricciones de las tablas que se están comprobando.

Las tablas de excepciones que utiliza el programa de utilidad de carga son idénticas a las que se describen aquí y, por lo tanto, se pueden volver a utilizar durante la comprobación de la sentencia SET INTEGRITY.

Normas para crear una tabla de excepciones

Las normas para crear una tabla de excepciones son las siguientes:

  • Si la tabla está protegida por una política de seguridad, la tabla de excepciones debe protegerse mediante la misma política de seguridad.
  • Las primeras n columnas de la tabla de excepciones son iguales que las columnas de la tabla que se está comprobando. Todos los atributos de columna, inclusive el nombre, el tipo de datos y la longitud, deben ser idénticos. En el caso de las columnas protegidas, la etiqueta de seguridad que protege a la columna debe ser la misma en ambas tablas.
  • Todas las columnas de la tabla de excepciones deben estar libres de restricciones y activadores. Las restricciones incluyen la integridad referencial, las restricciones de comprobación, así como las restricciones de índice exclusivo que podrían causar errores en la inserción.
  • La columna (n+1) de la tabla de excepciones es una columna TIMESTAMP opcional. Esto sirve para identificar las invocaciones sucesivas de la comprobación que efectúa la sentencia SET INTEGRITY en la misma tabla, si las filas de la tabla de excepciones no se han suprimido antes mediante la emisión de la sentencia SET INTEGRITY para comprobar los datos. La precisión de la indicación de fecha y hora puede ser cualquier valor de 0 a 12 y el valor asignado será el resultado del registro especial CURRENT TIMESTAMP
  • La columna (n+2) debe ser de tipo CLOB(32K) o mayor. Esta columna es opcional pero se recomienda incluirla y se utilizará para proporcionar los nombres de las restricciones que violan los datos de la fila. Si no se proporciona esta columna (como pasaría si, por ejemplo, la tabla original tuviese el número máximo de columnas permitido), sólo se copia la fila en la que se ha detectado la violación de restricción.
  • La tabla de excepciones se debe crear con las columnas (n+1) y (n+2).
  • No se impone ningún nombre en particular para las columnas adicionales indicadas anteriormente. No obstante, debe seguirse exactamente la especificación del tipo.
  • No se permiten columnas adicionales.
  • Si la tabla original tiene columnas generadas (incluida la propiedad IDENTITY), las columnas correspondientes de la tabla de excepciones no deben especificar la propiedad generada.
  • Los usuarios que invocan la sentencia SET INTEGRITY para comprobar datos deben tener el privilegio SET INSERT en las tablas de excepciones.
  • La tabla de excepciones no puede ser una tabla particionadas de datos, una tabla de agrupación en clúster de rangos ni una tabla desenlazada.
  • La tabla de excepciones no puede ser una tabla de consulta materializada ni una tabla de etapas.
  • La tabla de excepciones no puede tener ninguna tabla de consulta materializada de renovación inmediata dependiente ni ninguna tabla de etapas de propagación inmediata dependiente.

La información de la columna mensaje tiene la estructura siguiente:

Tabla 1. Estructura de la columna de mensajes de la tabla de excepciones
Número de campo Contenido Tamaño Comentarios
1 Número de violaciones de restricción 5 bytes Justificada por la derecha rellenada con 0
2 Tipo de la primera violación de restricción 1 byte
  • D - Violación de supresión de cascada
  • F - Violación de clave foránea
  • G - Violación de columna generada
  • I - Violación de índice exclusivoa
  • K - Violación de restricción de comprobación
  • L - Violación de normas de grabación de LBAC
  • P - Violación de particionamiento de datos
  • S - Etiqueta de seguridad de fila no válida
  • X - Índice definido sobre la violación de columna XMLd
3 Longitud de restricción/columnab /ID de índicec 5 bytes Justificada por la derecha rellenada con 0
4 Nombre de restricción/Nombre de columnab/ID de índicec longitud del campo anterior  
5 Separador 3 bytes <espacio><dos puntos><espacio>
6 Tipo de la siguiente violación de restricción 1 byte
  • D - Violación de supresión de cascada
  • F - Violación de clave foránea
  • G - Violación de columna generada
  • I - Violación de índice exclusivo
  • K - Violación de restricción de comprobación
  • L - Violación de normas de grabación de LBAC
  • P - Violación de particionamiento de datos
  • S - Etiqueta de seguridad de fila no válida
  • X - Índice definido sobre la violación de columna XMLd
7 Longitud de restricción/columna/ID de índice 5 bytes Justificada por la derecha rellenada con 0
8 Nombre de restricción/Nombre de columna/ID de índice longitud del campo anterior  
..... ..... ..... Repita del Campo 5 al 8 para cada violación
  • a No se producirán violaciones de índices exclusivos en la comprobación si se utiliza la sentencia SET INTEGRITY, a no ser que se realice después de una operación de enlace. Sin embargo, se informará de esto, cuando se ejecute LOAD si se elige la opción FOR EXCEPTION. Sin embargo, LOAD no informará de las violaciones de restricción de comprobación, columna generada, clave foránea, supresión en cascada ni de particionamiento de datos en las tablas de excepciones.
  • b Para recuperar la expresión de una columna generada a partir de las vistas de catálogo, utilice una sentencia de selección. Por ejemplo, si el campo 4 es MYSCHEMA.MYTABLE.GEN_1, entonces SELECT SUBSTR(TEXT, 1, 50) FROM SYSCAT.COLUMNS WHERE TABSCHEMA='MYSCHEMA' AND TABNAME='MYNAME' AND COLNAME='GEN_1'; devuelve los primeros 50 bytes de la expresión, en el formato AS (<expresión>)
  • c Para recuperar un ID de índice a partir de las vistas de catálogo, utilice una sentencia de selección. Por ejemplo, si el campo 4 es 1234, entonces SELECT INDSCHEMA, INDNAME FROM SYSCAT.INDEXES WHERE IID=1234.
  • d Para el índice definido sobre violación de columna XML, el nombre de restricción, el nombre de columna o el campo de ID de índice identifican la columna XML que tuvo una violación de integridad en uno de sus índices. No identifica el índice que contiene la violación de la integridad.Sólo identifica el nombre de la columna XML en la que se produce la violación del índice. Por ejemplo, el valor X00006XTCOLZ en la columna del mensaje indica que se ha producido una violación de índice en uno de los índices en la columna XTCOL2.

Gestión de las filas en una tabla de excepciones

La información de las tablas de excepciones se puede procesar de varias formas. Se pueden corregir datos y volver a insertar filas en las tablas originales.

Si no hay ningún activador INSERT en la tabla original, transfiera las filas corregidas emitiendo la sentencia INSERT con una subconsulta en la tabla de excepciones.

Si hay activadores INSERT y desea completar la operación de carga con las filas corregidas de las tablas de excepciones sin disparar los activadores:
  • Diseñe los activadores INSERT para que se disparen dependiendo del valor de una columna definida explícitamente para esta finalidad.
  • Descargue los datos de las tablas de excepciones y añádalos utilizando el programa de utilidad de carga. En ese caso, si desea volver a comprobar los datos, tenga en cuenta que la comprobación de restricciones no está confinada a las filas añadidas.
  • Guarde el texto de definición del activador de la vista de catálogos del sistema relevante. Después descarte el activador INSERT y utilice INSERT para transferir las filas corregidas de las tablas de excepciones. Finalmente, vuelva a crear el activador utilizando la definición de activador guardada.

No se realiza una provisión explícita para evitar que se disparen los activadores cuando se insertan filas desde las tablas de excepciones.

Sólo se informa de una violación por fila para las violaciones de índices exclusivos.

Si en la tabla hay valores con LONG VARCHAR, LONG VARGRAPHIC o tipos de datos LOB, los valores no se insertan en la tabla de excepciones si se producen violaciones de índices exclusivos.

Consulta de las tablas de excepciones

La estructura de la columna de mensajes de una tabla de excepciones es una lista concatenada de nombres de restricciones, longitudes y delimitadores, tal como se describe antes. Esta información se puede consultar.

Por ejemplo, para recuperar una lista de todas las violaciones, repitiendo cada fila con sólo el nombre de la restricción junto a ella, supongamos que la tabla T1 original tiene dos columnas: C1 y C2. Supongamos también que la tabla de excepciones correspondiente, E1, tiene las columnas C1 y C2, que se corresponden con las de la T1, así como una columna de mensajes, MSGCOL. La siguiente consulta utiliza la recurrencia para enumerar un nombre de restricción por fila (que pertenece a las filas que tienen más de una violación):
WITH IV  (C1, C2, MSGCOL, CONSTNAME, I, J) AS
 (SELECT C1, C2, MSGCOL,
     CHAR(SUBSTR(MSGCOL, 12,
                 INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,7,5)),5,0)))),
     1,
     15+INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,7,5)),5,0))
    FROM E1
  UNION ALL
  SELECT C1, C2, MSGCOL,
      CHAR(SUBSTR(MSGCOL, J+6,
                  INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,J+1,5)),5,0)))),
      I+1,
      J+9+INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,J+1,5)),5,0))
    FROM IV
    WHERE I < INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,1,5)),5,0))
 ) SELECT C1, C2, CONSTNAME FROM IV;
Para mostrar todas las filas que han violado una restricción concreta, la consulta anterior se puede ampliar de la siguiente manera:
WITH IV  (C1, C2, MSGCOL, CONSTNAME, I, J) AS
 (SELECT C1, C2, MSGCOL,
      CHAR(SUBSTR(MSGCOL, 12,
                  INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,7,5)),5,0)))),
      1,
      15+INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,7,5)),5,0))
    FROM E1
  UNION ALL
  SELECT C1, C2, MSGCOL,
      CHAR(SUBSTR(MSGCOL, J+6,
                 INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,J+1,5)),5,0)))),
      I+1,
      J+9+INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,J+1,5)),5,0))
    FROM IV
    WHERE I < INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,1,5)),5,0))
 ) SELECT C1, C2, CONSTNAME FROM IV WHERE CONSTNAME = 'nombrerestricción';
La consulta siguiente puede utilizarse para obtener todas las violaciones de restricciones de comprobación:
WITH IV  (C1, C2, MSGCOL, CONSTNAME, CONSTTYPE, I, J) AS
  (SELECT C1, C2, MSGCOL,
       CHAR(SUBSTR(MSGCOL, 12,
                   INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,7,5)),5,0)))),
       CHAR(SUBSTR(MSGCOL, 6, 1)),
       1,
       15+INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,7,5)),5,0))
     FROM E1
   UNION ALL
   SELECT C1, C2, MSGCOL,
       CHAR(SUBSTR(MSGCOL, J+6,
                  INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,J+1,5)),5,0)))),
       CHAR(SUBSTR(MSGCOL, J, 1)),
       I+1,
       J+9+INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,J+1,5)),5,0))
     FROM IV
     WHERE I < INTEGER(DECIMAL(VARCHAR(SUBSTR(MSGCOL,1,5)),5,0))
 ) SELECT C1, C2, CONSTNAME FROM IV WHERE CONSTTYPE = 'K';