ORA-30926: no se puede obtener un conjunto estable de filas en las tablas de origen

129

estoy obteniendo

ORA-30926: no se puede obtener un conjunto estable de filas en las tablas de origen

en la siguiente consulta:

  MERGE INTO table_1 a
      USING 
      (SELECT a.ROWID row_id, 'Y'
              FROM table_1 a ,table_2 b ,table_3 c
              WHERE a.mbr = c.mbr
              AND b.head = c.head
              AND b.type_of_action <> '6') src
              ON ( a.ROWID = src.row_id )
  WHEN MATCHED THEN UPDATE SET in_correct = 'Y';

Lo ejecuté table_1tiene datos y también ejecuté la consulta interna ( src) que también tiene datos.

¿Por qué vendría este error y cómo se puede resolver?

Omnipresente
fuente

Respuestas:

202

Esto generalmente es causado por duplicados en la consulta especificada en la cláusula USING. Esto probablemente significa que TABLE_A es una tabla primaria y el mismo ROWID se devuelve varias veces.

Puede resolver rápidamente el problema utilizando un DISTINCT en su consulta (de hecho, si 'Y' es un valor constante, ni siquiera necesita ponerlo en la consulta).

Suponiendo que su consulta es correcta (no conoce sus tablas), podría hacer algo como esto:

  MERGE INTO table_1 a
      USING 
      (SELECT distinct ta.ROWID row_id
              FROM table_1 a ,table_2 b ,table_3 c
              WHERE a.mbr = c.mbr
              AND b.head = c.head
              AND b.type_of_action <> '6') src
              ON ( a.ROWID = src.row_id )
  WHEN MATCHED THEN UPDATE SET in_correct = 'Y';
Popular
fuente
1
Esta es probablemente la razón por la que otros enfoques (para mí) también me devolvieron otros errores (como 'procedimiento, función, paquete o tipo no está permitido aquí' y 'No se puede modificar una columna que se correlaciona con un error de tabla sin clave conservada al intentar insertar en una vista '). ~ Si ayuda a alguien más, obtuve el mismo error incluso después de agregar distintivo hasta que reorganicé las uniones de mi consulta interna, así que comencé con la tabla que obtenía más de una fila devuelta y la interna se unió desde allí ... si eso tiene sentido.
jinglesthula
40

Probablemente esté intentando actualizar la misma fila de la tabla de destino varias veces. Acabo de encontrar el mismo problema en una declaración de fusión que desarrollé. Asegúrese de que su actualización no toque el mismo registro más de una vez en la ejecución de la fusión.

DCookie
fuente
1
+1, gracias, esto me acaba de suceder en una tabla de destino con una pequeña cantidad de duplicados (al menos en función de las teclas utilizadas en la fusión).
tbone
6

¿Cómo solucionar problemas de errores ORA-30926? (ID de documento 471956.1)

1) Identificar la declaración fallida

alterar los eventos del conjunto de sesiones '30926 seguimiento nombre errorstack nivel 3';

o

modificar los eventos configurados por el sistema '30926 seguimiento de error de pila de errores';

y observe los archivos .trc en UDUMP cuando ocurra.

2) Después de encontrar la instrucción SQL, verifique si es correcta (tal vez usando el plan de explicación o tkprof para verificar el plan de ejecución de la consulta) y analice o calcule estadísticas en las tablas en cuestión si esto no se ha hecho recientemente. La reconstrucción (o caída / recreación) de índices también puede ayudar.

3.1) ¿La instrucción SQL es una FUSIÓN? evalúe los datos devueltos por la cláusula USING para asegurarse de que no haya valores duplicados en la unión. Modifique la declaración de fusión para incluir una cláusula where determinista

3.2) ¿Es esta una declaración de ACTUALIZACIÓN a través de una vista? Si es así, intente completar el resultado de la vista en una tabla e intente actualizar la tabla directamente.

3.3) ¿Hay un disparador en la mesa? Intente deshabilitarlo para ver si aún falla.

3.4) ¿La declaración contiene una vista no fusionable en un 'IN-Subquery'? Esto puede provocar que se devuelvan filas duplicadas si la consulta tiene una cláusula "FOR UPDATE". Ver error 2681037

3.5) ¿La tabla tiene columnas no utilizadas? Dejarlos caer puede prevenir el error.

4) Si modificar el SQL no soluciona el error, el problema puede estar en la tabla, especialmente si hay filas encadenadas. 4.1) Ejecute la instrucción 'ANALIZAR TABLA DE ESTRUCTURA DE VALIDACIÓN DE TABLA' en todas las tablas utilizadas en el SQL para ver si hay alguna corrupción en la tabla o sus índices. 4.2) Verifique y elimine las FILAS EN CADENA o migradas en la tabla. Hay formas de minimizar esto, como la configuración correcta de PCTFREE. Nota de uso 122020.1 - Encadenamiento de filas y migración 4.3) Si la tabla también está organizada por índice, consulte: Nota 102932.1 - Monitoreo de filas encadenadas en IOT

Tagar
fuente
5

Tenía el error hoy en un 12c y ninguna de las respuestas existentes encajaba (sin duplicados, sin expresiones no deterministas en la cláusula WHERE). Mi caso estaba relacionado con esa otra posible causa del error, de acuerdo con el texto del mensaje de Oracle (énfasis a continuación):

ORA-30926: no se puede obtener un conjunto estable de filas en las tablas de origen
Causa: No se pudo obtener un conjunto estable de filas debido a la gran actividad de dml o una cláusula where no determinista.

La fusión fue parte de un lote más grande y se ejecutó en una base de datos en vivo con muchos usuarios concurrentes. No hubo necesidad de cambiar la declaración. Acabo de confirmar la transacción antes de la fusión, luego la ejecuté por separado y volví a realizarla. Entonces, la solución se encontró en la acción sugerida del mensaje:

Acción: elimine las cláusulas where no deterministas y vuelva a emitir el dml .

Cee McSharpface
fuente
Recibí ese mensaje de error al importar DataPump a través de la red (usando un NETWORK_LINKparámetro que se conecta directamente a la base de datos de origen) durante la etapa de recopilación de estadísticas, y su nota resaltada probablemente lo explica. Afortunadamente, solo las estadísticas se vieron afectadas.
Mark Stewart
1
SQL Error: ORA-30926: unable to get a stable set of rows in the source tables
30926. 00000 -  "unable to get a stable set of rows in the source tables"
*Cause:    A stable set of rows could not be got because of large dml
           activity or a non-deterministic where clause.
*Action:   Remove any non-deterministic where clauses and reissue the dml.

Este error me ocurrió debido a registros duplicados (16K)

Lo intenté con único funcionó .

pero de nuevo cuando intenté fusionar sin que ocurriera el mismo problema, la segunda vez se debió confirmar

después de fusionar si el commit no se realiza, se mostrará el mismo error.

Sin un único, la consulta funcionará si se proporciona confirmación después de cada operación de fusión.

v8-E
fuente
-1

Una aclaración adicional sobre el uso de DISTINCT para resolver el error ORA-30926 en el caso general:

Debe asegurarse de que el conjunto de datos especificado por la cláusula USING () no tenga valores duplicados de las columnas de unión , es decir, las columnas en la cláusula ON () .

En el ejemplo de OP donde la cláusula USING solo selecciona una clave, fue suficiente agregar DISTINCT a la cláusula USING. Sin embargo, en el caso general, la cláusula USING puede seleccionar una combinación de columnas clave para que coincida y columnas de atributos que se utilizarán en la cláusula UPDATE ... SET. Por lo tanto, en el caso general, agregar DISTINCT a la cláusula USING todavía permitirá diferentes filas de actualización para las mismas claves, en cuyo caso aún obtendrá el error ORA-30926.

Esta es una elaboración de la respuesta de DCookie y el punto 3.1 de la respuesta de Tagar, que según mi experiencia puede no ser inmediatamente obvio.

Durban_legend
fuente