2010-01-13 20 views
5

Estoy tratando de insertar una sola fila que puede existir o no. Me gustaría evitar seleccionarlo primero y/o obtener un -803 si existe. Investigué un poco e intenté ignorar y la declaración de combinación, pero sigo obteniendo errores de sintaxis en ambos. En cualquier caso, no estoy intentando copiar los datos de otra tabla, por lo tanto, fusionar no es realmente apropiado.
¿Hay alguna forma en DB2 SQL de simplemente emitir una inserción a prueba de fallas y no tener que codificar al respecto? En otras palabras, ¿hay alguna sintaxis de inserción que garantice que los datos se agregarán si no existe o devolverá el estado cero incluso si lo hace?Intentando evitar -803 en la inserción de DB2

Respuesta

2

En resumen, la respuesta es no. En largo, todo depende de las restricciones que haya establecido en su mesa. Si intenta ejecutar una inserción en una tabla que tiene una restricción única en una columna y ya existen datos que está intentando insertar, obtendrá un error en DB2 (y en cualquier otro RDBMS).

En este caso, su mejor opción es probablemente escribir un procedimiento almacenado que verifique si el registro ya existe antes de crearlo.

+2

Mejor aún: no pierda el tiempo haciendo la verificación de existencia, haga que el procedimiento almacenado haga la inserción, y solo maneja el error -803 (SQL0803N). Mejor aún: simplemente haga que la aplicación verifique el código de retorno desde el inserto y maneje el error -803. –

+0

Gracias por la respuesta rápida. Esperaba que DB2 tuviera algún equivalente al parámetro "ignorar", pero no tuve tanta suerte. Mike –

+0

Intenté manejar el -803 y hacer una actualización, pero esto deja un rastro de pila en el registro incluso cuando el proceso general es exitoso, lo que hace que otros hagan preguntas.Entonces, estoy cambiando el código para hacer una verificación de existencia primero. Gracias por todas las sugerencias. –

7

MERGE es es apropiado, ya que puede suministrar valores dinámicamente en la cláusula USING (vea el ejemplo 5 en http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.ibm.db2.udb.admin.doc/doc/r0010873.htm).

¡Pero MERGE es una función de DB2 V8.2! Probablemente estés en V8.1, ¿verdad?

Si implementa la comprobación de la existencia de esta manera:

SELECT 
if (found) UPDATE else INSERT 

tenga cuidado con problemas de concurrencia: Dos hilos concurrentes pueden tanto encontrar ninguna columna y luego ambos intente insertar, incluso si hay una transacción en todo el código de seguridad. Para asegurarse de que esto no ocurra, debe adquirir un bloqueo de actualización con Lectura repetible en la instrucción SELECT anterior utilizando WITH RR USE AND KEEP UPDATE LOCKS.

+0

¿Siguen siendo un problema los problemas de concurrencia si haces un 'INSERT', tomas el' -803' y luego haces el 'UPDATE'? –

2

Puede hacer la declaración de actualización, si eso devuelve 0 resultados actualizados, luego haga la instrucción de inserción.

2

Puede hacerlo utilizando la tabla sysibm.sysdummy (o la mejor llamada dual de Oracle o versiones posteriores de DB2). Esto funcionará muy bien para el caso en el que desee insertar una fila que no existe pero devuelva 0 si existe. AFAIK, no puedes actualizar una fila usando este método, necesitarás combinar para eso.

Para realizar esto, necesitará una clave primaria o única en su mesa. Se inserta en la tabla, seleccionando todos sus valores de dual en el proceso donde no existe una fila en su tabla que coincida con su índice primario o único.

insert into table (column1, column2, column3, column4, column5) 
select 'A', 'B', 'C', 'D', 'E' from dual where not exists (select * from table where column1 = 'A'); 

He encontrado esto muy útil para los casos en los que tengo múltiples procesos de inserción a una mesa y no puedo garantizar el orden de esas inserciones. Puede detectar si la inserción fue exitosa o no por el valor devuelto, que será 1 si fue exitoso o 0 si no es

Cuestiones relacionadas