Есть ли в DB2 оператор вставки или обновления? - PullRequest
35 голосов
/ 01 декабря 2008

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

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

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

Например:

insertupdate into mytable values ('myid')

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

Ответы [ 4 ]

40 голосов
/ 01 декабря 2008

Да, в 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

https://www.ibm.com/support/knowledgecenter/en/SS6NHC/com.ibm.swg.im.dashdb.sql.ref.doc/doc/r0010873.html

https://www.ibm.com/developerworks/community/blogs/SQLTips4DB2LUW/entry/merge?lang=en

15 голосов
/ 21 мая 2014

Я нашел эту ветку, потому что мне действительно нужна была одна строка для DB2 INSERT ИЛИ ОБНОВЛЕНИЯ.

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

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

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

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

9 голосов
/ 16 апреля 2013

Этот ответ, мы надеемся, полностью ответит на запрос, заданный MrSimpleMind в use-update-and-insert-in-same-query , и предоставит рабочий простой пример оператора DB2 MERGE со сценарием вставка И обновление за один раз (обновляется запись с идентификатором 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 голосов
/ 22 апреля 2014

Другой способ - выполнить эти 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 существует. Вторая вставляет строку в БД, если MyId не существует.

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

...