【问题标题】:Insert or Update multiple rows in Sql Server在 Sql Server 中插入或更新多行
【发布时间】:2014-11-25 10:58:43
【问题描述】:

我需要执行如下所示的查询。 KEY1 和 KEY2 列是不能重复的键。如果有键匹配,我需要执行更新 VAL 而不是插入。如何在 Sql Server 中做到这一点?

INSERT INTO tableA
  ( 
      KEY1,
      KEY2,
      VAL,                      
  ) VALUES (
          -- Row A
          'datakeyA1',
          'datakeyA2',
          'somevaluetoinsertorupdate'
      ) , (
          -- Row B
          'datakeyB1',
          'datakeyB2',
          'somevaluetoinsertorupdate'
      ) , (
          -- Row C
          'datakeyC1',
          'datakeyC2',
          'somevaluetoinsertorupdate'
      );

我尝试使用 MERGE,但查看语法,我不确定它是否支持更新/插入多行。如果有人过去遇到过类似的情况,请您帮忙吗?

编辑:

如果我使用的是 MySql,我会使用:

ON DUPLICATE KEY UPDATE 
 VAL = VALUES(VAL)

在查询中。

【问题讨论】:

  • MERGE 支持多行。为什么不呢?
  • 你在尝试Bulk insert / Update
  • 我试过WHEN NOT MATCHED THEN INSERT (KEY1,KEY2,VAL) VALUES ('datakeyA1', 'datakeyA1', 'datakeyA1'), ('datakeyB1', 'datakeyB1', 'datakeyB1');。这似乎是一个无效的语法。
  • 我正在尝试插入多行,但正在研究在现有数据中找到匹配键时如何进行更新而不是插入。 (即与 MySql 中的 ON DUPLICATE KEY UPDATE 功能相同

标签: php sql sql-server


【解决方案1】:

您可以使用table value constructor 作为源表,以使其与MERGE 一起工作:

MERGE tableA AS t
USING (VALUES 
        ('datakeyA1', 'datakeyA2', 'somevaluetoinsertorupdate'), 
        ('datakeyB1', 'datakeyB2', 'somevaluetoinsertorupdate'),
        ('datakeyC1', 'datakeyC2', 'somevaluetoinsertorupdate')
    ) AS s (Key1, Key2, Val)
        ON s.Key1 = t.Key1
        AND s.Key2 = t.Key2
WHEN MATCHED THEN 
    UPDATE 
    SET    Val = s.Val
WHEN NOT MATCHED THEN 
    INSERT (Key1, Key2, Val)
    VALUES (s.Key1, s.Key2, s.Val);

【讨论】:

  • 我正在寻找在单个查询中更新多行的解决方案,就像 INSERT INTO MyTable (a,b,c) VALUES (1,2,3),(3,4, 5),[...] 这确实做到了。谢谢
【解决方案2】:

尝试像这样使用 MERGE:

SQL Fiddle

MS SQL Server 2008 架构设置

CREATE TABLE tableA
(
    KEY1 VARCHAR(50),
    KEY2 VARCHAR(50),
    VAL VARCHAR(50)
    PRIMARY KEY (Key1, Key2)         
) 

INSERT INTO tableA
VALUES ('datakeyA1', 'datakeyA2', 'somevaluetoinsertorupdate')

查询 1

MERGE  tableA AS T
USING
    (VALUES ('datakeyA1','datakeyA2','SOME NEW VALUE'), 
            ('datakeyB1','datakeyB2','somevaluetoinsertorupdate'), 
            ('datakeyC1','datakeyC2','somevaluetoinsertorupdate')) AS S(Key1, Key2, Val) 
ON (S.Key1 = T.Key1 AND S.Key2 = T.Key2)
WHEN MATCHED
    THEN UPDATE SET T.Val = S.Val
WHEN NOT MATCHED BY TARGET
    THEN INSERT (Key1, Key2, VAL) VALUES (S.Key1, S.Key2, S.Val);

SELECT *
FROM tableA

Results

|      KEY1 |      KEY2 |                       VAL |
|-----------|-----------|---------------------------|
| datakeyA1 | datakeyA2 |            SOME NEW VALUE |
| datakeyB1 | datakeyB2 | somevaluetoinsertorupdate |
| datakeyC1 | datakeyC2 | somevaluetoinsertorupdate |

【讨论】:

    猜你喜欢
    • 2012-06-16
    • 2020-11-21
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 2013-06-15
    • 1970-01-01
    • 2021-04-29
    相关资源
    最近更新 更多