MERGE y ORA-30926

El error ORA-30926 es una extraño error que puede aparecer en sentencias ‘MERGE’ en las cuales la condición de ‘join’ puede dar lugar a inconsistencias. El problema es, como siempre, que el mensaje explicativo del error no clarifica demasiado las causas que lo motivan.

“ORA-30926: 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.”

Veamos un ejemplo:

carlos@db01.xxxxxx> select * from prueba01;

      ID_N C_TXT
---------- -------------------------
         1 UNO

carlos@db01.xxxxxx> select * from prueba02;

      ID_N C_TXT
---------- -------------------------
         2 TWO
         1 RAS
         1 ONE

carlos@db01.xxxxxx> merge into prueba01 a
  2  using prueba02 b
  3  on (a.id_n = b.id_n)
  4  when matched then update set a.c_txt = b.c_txt;
using prueba02 b
      *
ERROR en línea 2:
ORA-30926: no se ha podido obtener un juego de filas estable en las tablas de origen

La verdadera causa del error no está en el “large dml activity“, sino en el “non-deterministic where clause“: como ocurría aquí, dos filas de la tabla PRUEBA02 actualizarían una misma fila de la tabla PRUEBA01.

Pero, como también vimos aquí, hay una pequeña trampa para soslayar el error:

carlos@db01.xxxxxx> UPDATE /*+ BYPASS_UJVC */ ( SELECT a.ID_N a_ID_N,
  2                      a.C_TXT a_C_TXT,
  3                      b.ID_N b_ID_N,
  4                      b.C_TXT b_C_TXT
  5                 FROM PRUEBA01 a,
  6                      PRUEBA02 b
  7                WHERE a.ID_N = b.ID_N)
  8          SET a_C_TXT = b_C_TXT;

2 filas actualizadas.

carlos@db01.xxxxxx> select * from prueba02;

      ID_N C_TXT
---------- -------------------------
         2 TWO
         1 RAS
         1 ONE

carlos@db01.xxxxxx> select * from prueba01;

      ID_N C_TXT
---------- -------------------------
         1 ONE

La pregunta es: ¿funcionará el ‘hint’ tramposo con el MERGE?

La respuesta es NO:

carlos@db01.xxxxxx> merge /*+ BYPASS_UJVC */ into prueba01 a
  2  using prueba02 b
  3     on (a.id_n = b.id_n)
  4     when matched then update set a.c_txt = b.c_txt;
using prueba02 b
      *
ERROR en línea 2:
ORA-30926: no se ha podido obtener un juego de filas estable en las tablas de origen

Finalmente, para los hombres -y mujeres- de poca fe: sin el HINT tramposo, el UPDATE tampoco funciona:

carlos@db01.xxxxxx> UPDATE  ( SELECT a.ID_N a_ID_N,
  2                      a.C_TXT a_C_TXT,
  3                      b.ID_N b_ID_N,
  4                      b.C_TXT b_C_TXT
  5                 FROM PRUEBA01 a,
  6                      PRUEBA02 b
  7                WHERE a.ID_N = b.ID_N)
  8          SET a_C_TXT = b_C_TXT;
        SET a_C_TXT = b_C_TXT
            *
ERROR en línea 8:
ORA-01779: no se puede modificar una columna que se corresponde con una tabla no reservada por clave

Saludos.

Carlos.

Anuncios

One Response to MERGE y ORA-30926

  1. Enrique dice:

    Gracias, lo arregle aplicando un distinct sobre pruba02…

    Enrique.
    _____________

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: