Подтвердить что ты не робот

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

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

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

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

Например:

insertupdate into mytable values ('myid')

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

4b9b3361

Ответ 2

Я нашел этот поток, потому что мне действительно нужен один-лайнер для 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')

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

Ответ 3

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

Ответ 4

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