DB2是否有"插入或更新"语句?

Mik*_*son 37 sql database db2 upsert insert-update

从我的代码(Java)我想确保在执行代码后数据库(DB2)中存在一行.

我的代码现在执行了一个select,如果没有返回结果,它会执行insert.我真的不喜欢这个代码,因为它在多线程环境中运行时会让我遇到并发问题.

我想要做的是将这个逻辑放在DB2而不是我的Java代码中.DB2有insert-or-update声明吗?或者我可以使用的任何类似的东西?

例如:

insertupdate into mytable values ('myid')
Run Code Online (Sandbox Code Playgroud)

另一种方法可能是始终执行insert并捕获"SQL-code -803主键已存在",但我想尽可能避免这种情况.

Win*_*ith 41

是的,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]
Run Code Online (Sandbox Code Playgroud)

看到:

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

  • 示例很有用:__merge到mytable使用(values('col1','col2'))作为匹配的mytable.code = tmp.code上的tmp(代码,名称)然后更新set name = col2'__ (3认同)
  • DB2 对合并语句有一些过时的限制。#1 关于合并完成的插入/更新/删除数量的统计数据是垃圾,这是记录在案的。#2. 更重要的是,如果您需要从在插入时自动创建 ID 的列中返回标识值,则无法使用 Merge 执行此操作。IDENTITY_VAL_LOCAL 无法获取与插入关联的新 ID。我曾担任过 DBA 并针对如此多的数据库进行过编程,而 DB2 是我 25 年多以来所经历过的最古怪、最困难、最奇怪、过时的特性数据库。 (3认同)

tek*_*aul 15

我找到了这个线程,因为我真的需要DB2 INSERT或UPDATE的单线程.

以下语法似乎有效,无需单独的临时表.

它通过使用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)
;
Run Code Online (Sandbox Code Playgroud)

如果必须插入多行,则可以重复VALUES部分而不必复制其余部分.

VALUES 
    (123, 'text'),
    (456, 'more')
Run Code Online (Sandbox Code Playgroud)

结果是一个语句可以插入或更新一行或多行,可能是一个原子操作.


小智 11

这个响应有希望完全回答MrSimpleMind在use-update-and-insert-in-same-query中的查询,并提供DB2 MERGE语句的一个有效的简单示例,其中包含一次插入和更新的方案(记录与更新ID 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;
Run Code Online (Sandbox Code Playgroud)

  • 我想指出的是,某些ibm数据库使用SYSIBM.SYSDUMMY1作为虚拟表而不是SYSIBM.DUAL。 (2认同)