ORA-30926: невозможно получить стабильный набор строк в исходных таблицах - PullRequest
112 голосов
/ 25 февраля 2010

Я получаю

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), который также имеет данные.

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

Ответы [ 6 ]

176 голосов
/ 25 февраля 2010

Это обычно вызывается дубликатами в запросе, указанном в предложении 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';
38 голосов
/ 25 февраля 2010

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

5 голосов
/ 02 апреля 2016

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

1) Определите ошибочный оператор

изменить события набора сеансов ‘30926 имя стека ошибок трассировки уровня 3’;

или

изменить системные системные события ‘30926 вычеркнуты ошибки имени трассировки’;

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

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

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

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

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

3.4) Содержит ли оператор не объединяемое представление в IN-Subquery? Это может привести к дублированию строк, если в запросе есть предложение «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

4 голосов
/ 21 июня 2016

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

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

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

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

1 голос
/ 26 июля 2018
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 сработает, если после каждой операции слияния будет зафиксирован коммит.

0 голосов
/ 14 февраля 2019

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

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

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

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

...