Предложение Oracle Merge Into для использования? - PullRequest
0 голосов
/ 21 февраля 2019

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

Попытка следовать документации об операторе Merge из справочника по языку Oracle Oracle Я создал инструкцию MERGE INTO ниже.Компилируется, но не работает правильно. Когда ON ( tbl.field_name = S.field_name ) оценивается как False логика не передается в (КОГДА НЕ СОГЛАСОВАНО) секцию

    MERGE INTO table_name tbl
         USING (SELECT field_name FROM table_name WHERE field_name = '12345') S
         ON (tbl.field_name = S.field_name)

         WHEN MATCHED THEN UPDATE . . . 
            -- flow arrives here when expected, this works correctly 

         WHEN NOT MATCHED THEN INSERT . . .
            -- When a match against (field_name) doesn't exist **flow never comes here?

Оператор MERGE INTO ниже работает правильно, но я не понимаю, почему он работает правильно.Сотрудник, который сейчас секвестрировал, помог мне с этим, а затем остался без объяснения причин.Она изменила только пункты USING и ON.Я пытаюсь понять, как часть ( USING Dual ) заставляет это работать правильно? или , почему пункт USING (в приведенном выше примере сявный SELECT) не работает должным образом? Кто-нибудь может мне помочь с этим?

    MERGE INTO table_name tbl
         USING dual
         ON (tbl.field_name = '12345')

         WHEN MATCHED THEN UPDATE . . . 
            -- flow arrives here when expected, this works correctly

         WHEN NOT MATCHED THEN INSERT . . .
            -- When a match against (field_name) doesn't exist **flow arrives here correctly

Ответы [ 2 ]

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

Я думаю, что вы смотрите на сравнение между исходной и целевой таблицами неправильно.

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

С:

     USING (SELECT field_name FROM table_name WHERE field_name = '12345') S
     ON (tbl.field_name = S.field_name)

, если в исходной таблице есть строка с этим значением, тогда S имеет одну строку(при условии, что он уникален), и в целевой таблице может быть или не быть совпадающей строки;он будет входить либо в совпавшие, либо в несоответствующие предложения, как и ожидалось, в зависимости от того, что находится в целевой таблице, но только с использованием значений из выбранной исходной строки.

Но если в исходной таблице нет строки стогда это значение S является пустым результирующим набором, поэтому предложение ON ничего не может сделать, поэтому оно никогда не оценивается - и в этом случае оно не достигает несоответствующего условия.Нечего сравнивать, и «ничто» не соответствует или и не соответствует ничему другому.

Принимая во внимание:

     USING dual
     ON (tbl.field_name = '12345')

всегда есть ровно однострока в dual, поэтому предложение ON всегда оценивается - хотя на самом деле он не использует эту строку dual или ее столбец dummy - и в целевой таблице может быть или не быть соответствующей записи,так что это переходит в ожидаемую ветку.Вы не можете иметь пустой результирующий набор из исходной таблицы, так как он теперь dual, который не может быть пустым.

В любом случае кажется, что ваше несоответствующее предложение, по крайней мере, неиспользуя данные из S, что обычно имеет место - в противном случае версия dual будет работать либо.

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

Когда '12345' не найдено в table_name.field_name, в первом случае вы используете таблицу без строк.Элемент управления перемещается в ветку when not matched then insert... (не уверен, почему вы так думаете), но вставлять нечего, поскольку S пусто.Во втором примере, даже если это значение не найдено, вы используете таблицу dual, которая имеет одну строку.Независимо от того, что находится в частях кода, которыми вы не делитесь с нами, вы ДОЛЖНЫ абсолютно ожидать различного поведения от двух разных операторов MERGE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...