Понимание MERGE INTO с hsqldb

У меня есть пустая таблица, и я хотел бы вставить какую-то строку, если ее еще нет. Я пробовал 3 (основных) варианта утверждений. Первый работает, второй ошибку не выдает но ничего не вставляет, третий вообще выдает ошибку.

Я хотел бы понять, почему второе утверждение ничего не делает.

Первый (вставляет):

MERGE INTO tags ta USING
 (VALUES 91852, 'G') temp (fid, tag) 
 ON temp.fid = ta.fid
 WHEN NOT MATCHED THEN
 INSERT (fid, tag) VALUES (temp.fid, temp.tag);

Второй (не вставляет):

MERGE INTO tags ta USING
 (SELECT fid, tag FROM tags i WHERE i.fid=91852 AND i.tag='G') temp (fid, tag) 
 ON temp.fid = ta.fid
 WHEN NOT MATCHED THEN
 INSERT (fid, tag) VALUES (91852, 'G');

Если SELECT ничего не возвращает, тогда должен срабатывать оператор NOT MATCHED, верно?

Третий (с ошибкой):

sql> MERGE INTO tags ta USING
 (SELECT fid, tag FROM tags i WHERE i.fid=91852 AND i.tag='G') temp (fid, tag) 
 ON temp.fid = ta.fid
 WHEN NOT MATCHED BY temp THEN
 INSERT (fid, tag) VALUES (91852, 'G');

  +>   +>   +>   +> SEVERE  SQL Error at '<stdin>' line 183:
"MERGE INTO tags ta USING
 (SELECT fid, tag FROM tags i WHERE i.fid=91852 AND i.tag='G') temp (fid, tag) 
 ON temp.fid = ta.fid
 WHEN NOT MATCHED BY temp THEN
 INSERT (fid, tag) VALUES (91852, 'G')"
unexpected token: BY required: THEN : line: 4
sql> sql> 

Последняя версия была вдохновлена ​​https://stackoverflow.com/a/30938729/4142984, которая предназначена для sql-сервера. , а не для hsqldb.


person Gyro Gearloose    schedule 04.02.2016    source источник


Ответы (1)


Часть SELECT оператора слияния — это ваш исходный набор. Если он пустой, то ничего не вставится, потому что не с чем совпадать. У вас просто пустой набор результатов.

В общем случае MERGE берет результирующий набор, полученный вашим предложением USING, и объединяет его с вашим условием ON. Затем вы можете сказать, что делать для обеих возможностей. Если он соответствует условию, вы можете обновить запись, если нет, вы можете вставить ее. Данные для обновления или вставки поступают из предложения USING, поэтому, если ваш набор результатов USING пуст, вам нечего сопоставлять и нечего вставлять.

person Matze    schedule 04.02.2016
comment
Я не уверен, что понимаю это правильно. Зачем, см. здесь stackoverflow.com/a/30938729/4142984 выбрать значение null в качестве работы test1? Потому что есть строка (хоть и нулевая) вместо моего примера, где строк вообще нет? - person Gyro Gearloose; 04.02.2016
comment
Хм, может быть. Мне кажется крайний случай. Я не особо разбираюсь в hsqldb, должен признаться. Но да, разница между SELECT NULL... и пустым результирующим набором все же есть. - person Matze; 04.02.2016
comment
Ответ правильный. Никаких действий не предпринимается, если исходный набор строк не содержит строк. - person fredt; 04.02.2016