Solucionando el problema SQL0803N

Posted by

SQL0803N es un mensaje de error que significa que la sentencia SQL recién emitida falló debido a la violación de una restricción única dentro de la base de datos. La “N” al final de este error significa que esta sentencia falló y no se ejecutó, pero que probablemente no sea un problema de la base de datos. Consulte Conceptos básicos de Db2: Mensajes de error para obtener más información general sobre la interpretación de mensajes de error de Db2.

¿Qué aspecto tiene este error?

Al igual que con cualquier mensaje de error en Db2, es fundamental obtener el texto completo del mensaje para solucionar el problema. Aquí hay un ejemplo de cómo debería ser ese resultado completo:

insert into dbi_repos.MONITORED_DB_PARTS (db_id ,db_part_num ,coll_id ,server_name ,db_login_id ,db_login_crypt_pwd ,is_monitored ,is_catlg_node) VALUES (1 ,0 ,1 ,'example.com' ,'db2inst1' ,'test' ,'N' ,'Y')

DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL0803N  One or more values in the INSERT statement, UPDATE statement, or
foreign key update caused by a DELETE statement are not valid because the
primary key, unique constraint or unique index identified by "1" constrains
table "DBI_REPOS.MONITORED_DB_PARTS_1" from having duplicate values for the
index key.  SQLSTATE=23505

Si no está emitiendo el comando en una línea de comando Db2, este mensaje puede estar oculto entre los mensajes de salida (logs) de la aplicación. También se puede recibir como un error -803. Cada aplicación que accede a una base de datos debe registrar errores como este en detalle: la verificación de errores es un componente crítico de cualquier aplicación. Los mensajes de salida de una aplicación pueden parecerse un poco más a esto:

DB2 SQL Error: SQLCODE=-803, SQLSTATE=23505, SQLERRMC=1;DBI_REPOS.MONITORED_DB_PARTS_1

Identificando el problema real

En los mensajes de error anteriores, he resaltado las piezas críticas de información en rojo. Incluso si no tiene el texto completo del mensaje de error en el log de una aplicación, estas dos piezas de información deberían devolverse en la salida reducida disponible. Esta información nos dice en este caso que estamos violando el índice número 1 en la tabla DBI_REPOS.MONITORED_DB_PARTS_1. Ahora que tengo esa información, puedo ejecutar una consulta simple para mostrarme qué columnas tienen datos duplicados cuando no deberían:

select substr(indname,1,32) as indname
  , substr(colnames,1,50) as colnames 
from syscat.indexes 
where tabschema='DBI_REPOS' 
  and tabname='MONITORED_DB_PARTS_1' 
  and iid=1 
with ur

INDNAME                          COLNAMES
-------------------------------- --------------------------------------------------
PX_MONDBPARTS                    +DB_ID+DB_PART_NUM

  1 record(s) selected.

Los valores que se deben cambiar en esta consulta para que coincidan con el mensaje de error específico están en rojo. Tenga en cuenta que el esquema y el nombre de la tabla deben estar en mayúsculas o en mayúsculas y minúsculas específicas si ha sido usted tan malvado como para forzar los nombres de las tablas en mayúsculas y minúsculas.

En este caso, podemos ver que la instrucción intentaba usar valores duplicados para la combinación de DB_ID y DB_PART_NUM. Esta combinación de valores ya existía en la tabla. Puedo verificar eso usando una instrucción sql que está mucho más personalizada para la tabla. En este caso, usaría:

select * 
from dbi_repos.MONITORED_DB_PARTS 
where DB_ID=1 
  and DB_PART_NUM=0 
with ur

DB_ID       DB_PART_NUM COLL_ID     SERVER_NAME                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      DB_LOGIN_ID                                                                                                                      DB_LOGIN_CRYPT_PWD                                                                                                               IS_CATLG_NODE IS_MONITORED
----------- ----------- ----------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- ------------- ------------
          1           0          21 somesillydbserver.example.com                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    db2inst1                                                                                                                         XXXXXXXXXXXXXXXXXXXX                                                                                                             Y             Y

  1 record(s) selected.

Los valores que estoy utilizando aquí para DB_ID y DB_PART_NUM son los valores de mi sentencia de inserción original.

Resolviendo el error

Las opciones para resolver este problema son:

  • Modifique los datos que se están insertando para que no entren en conflicto con los datos que ya están en la tabla.
  • Corrija los datos que ya están en la tabla para asegurarse de que los valores no entren en conflicto con lo que se está insertando.

La solución a este mensaje de error es casi siempre cambiar de alguna manera los datos que intenta insertar a la tabla.

Este no es un problema del sistema de base de datos y, en general, todo lo que un DBA puede hacer es ayudarlo con este análisis para descubrir qué está mal con los datos.

Leave a Reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.