Есть ли у DB2 инструкция «вставить или обновить»?

Из моего кода (Java) я хочу убедиться, что строка существует в базе данных (DB2) после моего кода.

Мой код теперь выполняет select и если результат не возвращается, он insert . Мне действительно не нравится этот код, поскольку он предоставляет мне проблемы параллелизма при работе в многопоточной среде.

То, что я хотел бы сделать, это поместить эту логику в DB2, а не в код Java. У DB2 есть инструкция insert-or-update ? Или что-нибудь подобное, что я могу использовать?

Например:

 insertupdate into mytable values ('myid') 

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

Да, DB2 имеет оператор MERGE, который будет выполнять UPSERT (обновление или вставка).

 MERGE INTO target_table USING source_table ON match-condition {WHEN [NOT] MATCHED THEN [UPDATE SET ...|DELETE|INSERT VALUES ....|SIGNAL ...]} [ELSE IGNORE] 

Видеть:

http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.ibm.db2.udb.admin.doc/doc/r0010873.htm

Я нашел этот поток, потому что мне действительно нужен один-лайнер для DB2 INSERT или UPDATE.

Кажется, что работает следующий синтаксис, не требуя отдельной таблицы temp.

Он работает с помощью VALUES () для создания структуры таблицы. SELECT * кажется излишним IMHO, но без него я получаю синтаксические ошибки.

 MERGE INTO mytable AS mt USING ( SELECT * FROM TABLE ( VALUES (123, 'text') ) ) AS vt(id, val) ON (mt.id = vt.id) WHEN MATCHED THEN UPDATE SET val = vt.val WHEN NOT MATCHED THEN INSERT (id, val) VALUES (vt.id, vt.val) ; 

если вам нужно вставить несколько строк, часть VALUES может быть повторена без дублирования остальных.

 VALUES (123, 'text'), (456, 'more') 

Результатом является один оператор, который может ВСТАВИТЬ ИЛИ ОБНОВИТЬ одну или несколько строк, предположительно, как атомную операцию.

Этот ответ должен, мы надеемся, полностью ответить на запрос, который MrSimpleMind имел в использовании-update-and-insert-in-same-query, и предоставить рабочий простой пример оператора DB2 MERGE с сценарием вставки и обновления за один раз (запись с ID 2 обновляется и вставляется идентификатор записи 3).

 CREATE TABLE STAGE.TEST_TAB ( ID INTEGER, DATE DATE, STATUS VARCHAR(10) ); COMMIT; INSERT INTO TEST_TAB VALUES (1, '2013-04-14', NULL), (2, '2013-04-15', NULL); COMMIT; MERGE INTO TEST_TAB T USING ( SELECT 3 NEW_ID, CURRENT_DATE NEW_DATE, 'NEW' NEW_STATUS FROM SYSIBM.DUAL UNION ALL SELECT 2 NEW_ID, NULL NEW_DATE, 'OLD' NEW_STATUS FROM SYSIBM.DUAL ) AS S ON S.NEW_ID = T.ID WHEN MATCHED THEN UPDATE SET (T.STATUS) = (S.NEW_STATUS) WHEN NOT MATCHED THEN INSERT (T.ID, T.DATE, T.STATUS) VALUES (S.NEW_ID, S.NEW_DATE, S.NEW_STATUS); COMMIT; 

Другой способ – выполнить эти 2 запроса. Это проще, чем создать оператор MERGE:

 update TABLE_NAME set FIELD_NAME=xxxxx where MyID=XXX; INSERT INTO TABLE_NAME values (MyField1,MyField2) WHERE NOT EXISTS(select 1 from TABLE_NAME where MyId=xxxx); 

Первый запрос просто обновляет поле, которое вам нужно, если MyId существует. Вторая вставляет строку в db, если MyId не существует.

В результате в вашем db выполняется только один из запросов.