ORA-30926: unable to get a stable set of rows in the source tables.
Normalmente este error se produce cuando en la operación Merge a una fila destino que hay que actualizar le corresponden más de una fila en la tabla origen. Como el motor no sabe qué registro escoger devuelve un error. Es un problema de duplicidad en la tabla origen.
Ejemplo:
- Tenemos:
TABLA_ORIGEN con los valores
ID Descripcion
1 'El primer valor'
1 'El valor con id duplicado'
2 'Otro valor' Y TABLA_DESTINO con los valores
ID Descripcion
1 'Valor a actualizar'
2 'Este no dará problemas'
3 'Este se queda igual'
- Queremos hacer un merge utilizando la siguiente sentencia:
MERGE into TABLA_DESTINO dest
USING TABLA_ORIGEN ori
ON (dest.ID = ori.ID)
WHEN MATCHED THEN UPDATE SET a.Descripcion = b.Descripcion;
USING TABLA_ORIGEN ori
ON (dest.ID = ori.ID)
WHEN MATCHED THEN UPDATE SET a.Descripcion = b.Descripcion;
Con estos datos obtendríamos el siguiente error sobre TABLA_ORIGEN:
ORA-30926: no se ha podido obtener un juego de filas estable en las tablas de origen
ORA-30926: no se ha podido obtener un juego de filas estable en las tablas de origen
- Ante este error tenemos 3 opciones: 1-. Eliminar los registros duplicados de la tabla origen:
DELETE FROM TABLA_ORIGEN WHERE id=1 AND Descripcion='El valor con id duplicado'
2-. Revisar las claves por las que hacemos la join en el merge:
Si utilizamos también el campo Descripcion en el enlace ya sólo habrá cero o un registro origen para cada destino:
MERGE into TABLA_DESTINO dest
USING TABLA_ORIGEN ori
ON (dest.ID = ori.ID AND dest.Descripcion=ori. Descripcion)WHEN MATCHED THEN UPDATE SET a.Descripcion = b.Descripcion;
MERGE into TABLA_DESTINO dest
USING TABLA_ORIGEN ori
ON (dest.ID = ori.ID AND dest.Descripcion=ori.
(En este ejemplo no tiene mucho sentido porque la tabla son sólo estos dos campos, y además la join no encontrará coincidencias)
3-. Utilizar en lugar del MERGE un UPDATE con JOIN y el HINT /*+BYPASS_UJVC */ para saltarnos la validación del motor, y cruzar los dedos:
UPDATE /*+ BYPASS_UJVC */
( SELECT ori.ID ori_ID,
ori.Descripcion ori_Descripcion,
dest.ID dest_ID,
dest.Descripcion dest_Descripcion
FROM TABLA_ORIGEN ori, TABLA_DESTINO dest
WHERE ori.ID = dest.ID)
SET dest_Descripcion = ori_Descripcion;
( SELECT ori.ID ori_ID,
ori.Descripcion ori_Descripcion,
dest.ID dest_ID,
dest.Descripcion dest_Descripcion
FROM TABLA_ORIGEN ori, TABLA_DESTINO dest
WHERE ori.ID = dest.ID)
SET dest_Descripcion = ori_Descripcion;
Obviamente las más recomendables son la primera o la segunda, según el caso.
No hay comentarios:
Publicar un comentario