ORA-30926: невозможно получить стабильный набор строк в исходных таблицах

129

я получаю

ORA-30926: невозможно получить стабильный набор строк в исходных таблицах

в следующем запросе:

  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';

Я запускал table_1его с данными, а также я запускал внутренний запрос ( src), который также имеет данные.

Почему возникла эта ошибка и как ее решить?

вездесущий
источник

Ответы:

202

Обычно это вызвано дублированием в запросе, указанном в предложении USING. Это, вероятно, означает, что TABLE_A является родительской таблицей и один и тот же ROWID возвращается несколько раз.

Вы можете быстро решить проблему, используя DISTINCT в своем запросе (фактически, если «Y» - постоянное значение, вам даже не нужно помещать его в запрос).

Предполагая, что ваш запрос правильный (вы не знаете свои таблицы), вы можете сделать что-то вроде этого:

  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';
Поп
источник
1
Вероятно, поэтому другие подходы (для меня) также вернули мне другие ошибки (например, «процедура, функция, пакет или тип здесь не разрешены» и «Невозможно изменить столбец, который сопоставляется с ошибкой таблицы без сохранения ключа при попытке вставить в представление '). ~ Если это помогает кому-то еще, я получал ту же ошибку даже после добавления отдельного в, пока я не перестроил свои соединения внутреннего запроса, поэтому я начал с таблицы, которая возвращала более одной строки и внутреннее объединение оттуда ... если это имеет смысл.
jinglesthula
40

Вероятно, вы пытаетесь обновить одну и ту же строку целевой таблицы несколько раз. Я только что столкнулся с той же проблемой в разработанном мной операторе слияния. Убедитесь, что ваше обновление не затрагивает одну и ту же запись более одного раза при выполнении слияния.

DCookie
источник
1
+1, спасибо, это случилось со мной на целевой таблице с небольшим количеством дубликатов (по крайней мере, на основе ключей, используемых при слиянии).
tbone
6

Как устранить ошибки ORA-30926? (ID документа 471956.1)

1) Определите ошибочное утверждение

изменить события набора сеансов '30926 имя трассировки errorstack level 3';

или

изменить системные события '30926 имя трассировки errorstack off';

и следите за файлами .trc в UDUMP, когда это происходит.

2) Найдя оператор SQL, проверьте его правильность (возможно, используя план объяснения или tkprof для проверки плана выполнения запроса) и проанализируйте или вычислите статистику по соответствующим таблицам, если это не было сделано в последнее время. Также может помочь восстановление (или удаление / воссоздание) индексов.

3.1) Является ли оператор SQL MERGE? оцените данные, возвращаемые предложением USING, чтобы убедиться, что в объединении нет повторяющихся значений. Измените оператор слияния, чтобы включить детерминированное предложение where

3.2) Это оператор UPDATE через представление? Если да, попробуйте заполнить результат просмотра в таблице и попробуйте обновить таблицу напрямую.

3.3) Есть ли на столе триггер? Попробуйте отключить его, чтобы проверить, не работает ли он по-прежнему.

3.4) Содержит ли оператор представление, не допускающее слияния, во 'IN-подзапросе'? Это может привести к возврату повторяющихся строк, если в запросе есть предложение FOR UPDATE. См. Ошибку 2681037

3.5) Есть ли в таблице неиспользуемые столбцы? Их удаление может предотвратить ошибку.

4) Если изменение SQL не устраняет ошибку, проблема может заключаться в таблице, особенно если есть связанные строки. 4.1) Запустите оператор ANALYZE TABLE VALIDATE STRUCTURE CASCADE для всех таблиц, используемых в SQL, чтобы увидеть, есть ли какие-либо повреждения в таблице или ее индексах. 4.2) Проверьте и удалите все СВЯЗАННЫЕ или перенесенные СТРОКИ в таблице. Есть способы минимизировать это, например, правильная установка PCTFREE. Используйте примечание 122020.1 - Сцепление строк и миграция 4.3) Если таблица дополнительно упорядочена по индексу, см .: Примечание 102932.1 - Мониторинг связанных строк в IOT

Tagar
источник
5

Была ошибка сегодня на 12c, и ни один из существующих ответов не подошел (нет дубликатов, нет недетерминированных выражений в предложении WHERE). Согласно тексту сообщения Oracle (курсив ниже) мой случай был связан с другой возможной причиной ошибки:

ORA-30926: невозможно получить стабильный набор строк в исходных таблицах
Причина : не удалось получить стабильный набор строк из-за большой активности dml или недетерминированного предложения where.

Слияние было частью большого пакета и было выполнено в действующей базе данных с множеством одновременных пользователей. Заявление менять не было. Я просто зафиксировал транзакцию перед слиянием, затем запустил слияние отдельно и снова зафиксировал. Итак, решение было найдено в предложенном действии сообщения:

Действие: Удалите все недетерминированные предложения where и повторно введите dml .

Си МакШарпфейс
источник
Я получал это сообщение об ошибке при импорте DataPump через сеть (с использованием NETWORK_LINKпараметра, который напрямую подключается к исходной базе данных) на этапе сбора статистики, и ваша выделенная заметка, вероятно, объясняет это. К счастью, пострадала только статистика.
Марк Стюарт,
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.

Эта ошибка возникла у меня из-за повторяющихся записей (16K)

Я пробовал с уникальным заработком .

но снова, когда я попытался выполнить слияние без уникальной такой же проблемы, произошел второй раз, это было связано с фиксацией

после слияния, если фиксация не выполнена, будет показана такая же ошибка.

Без уникальности Query будет работать, если после каждой операции слияния выполняется фиксация.

v8-E
источник
-1

Дальнейшее разъяснение использования DISTINCT для устранения ошибки ORA-30926 в общем случае:

Вам необходимо убедиться, что набор данных, указанный в предложении USING (), не имеет повторяющихся значений столбцов соединения , то есть столбцов в предложении ON (). .

В примере OP, где предложение USING выбирает только ключ, было достаточно добавить DISTINCT к предложению USING. Однако в общем случае предложение USING может выбрать комбинацию ключевых столбцов для сопоставления и столбцов атрибутов, которые будут использоваться в предложении UPDATE ... SET. Таким образом, в общем случае добавление DISTINCT к предложению USING по-прежнему разрешает разные строки обновления для одних и тех же ключей, и в этом случае вы все равно получите ошибку ORA-30926.

Это разработка ответа DCookie и пункта 3.1 в ответе Тагара, который, по моему опыту, может быть не сразу очевиден.

Durban_legend
источник