如果存在 UPDATE else INSERT 对于表的每一行

Art*_*Rey 3 sql-server insert-update

我有一个名为 tableFrom 的表想要插入到名为 tableTo 的表中。插入效果很好,但是如果我再次插入相同的值,则会出现重复键错误。所以我只想更新已经存在的行。我知道命令 ON DUPLICATE with MySQL,不幸的是在 SQL Server 中丢失了。

如果我只想检查一个精确的行,这很容易:

IF EXISTS PK = @PK
Run Code Online (Sandbox Code Playgroud)

但是我正在尝试为整张桌子这样做,我不知道是否可能。我想用游标检查每一行,我是 SQL 的新手。

这是我想出的:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
IF EXISTS   (
            SELECT 
                1 
            FROM 
                tableFrom F,
                tableTo T
            WHERE 
                T.product = F._product
            )
    BEGIN
        UPDATE
            tableTo
        SET
            T.something = F.something
        FROM
            tableTo T
                INNER JOIN 
                    tableFrom F
                ON
                    T.product = F._product
    END
ELSE
    BEGIN
        INSERT INTO tableTo
            (product, 
            something)
        SELECT
            F._product, 
            F.something
        FROM
            tableFrom F
    END
COMMIT TRANSACTION
Run Code Online (Sandbox Code Playgroud)

UPDATE 部分工作正常,但没有完成 INSERT。

编辑1:

试过这个代码:

MERGE tableTo AS T
USING tableFrom AS S
    ON (T.product= S._product)
WHEN NOT MATCHED BY TARGET
    THEN INSERT(product, something) VALUES(S._product, S.something)
WHEN MATCHED 
    THEN UPDATE SET T.Something= S.Something
Run Code Online (Sandbox Code Playgroud)

出现以下错误:“'MERGE' 附近的语法不正确。您可能需要将当前数据库的兼容级别设置为更高的值才能启用此功能。请参阅 ALTER DATABASE 的 SET COMPATIBILITY_LEVEL 选项的帮助。”

编辑2:

我用谷歌搜索了上面的错误消息,它似乎是由于在 MERGE 语句之前的最后一行末尾缺少分号。MERGE 命令运行完美!

Pan*_*vos 7

它没有丢失。SQL Server 实现了标准 MERGE语句,它允许您指定在源和目标之间发生或不发生匹配时会发生什么。查看文档以获取示例。

使用可能涉及许多列的条件进行匹配。MERGE允许您在以下情况下执行 INSERT、UPDATE 或 DELETE:

  • 根据条件找到匹配项
  • 匹配仅发生在源中
  • 匹配只发生在目标

通过这种方式,您可以更新现有行、插入仅存在于源中的行、删除仅出现在目标中的行。

在您的情况下,您可以执行以下操作:

MERGE tableTo AS T
USING tableFrom AS S
      ON (T.product= S._product)
WHEN NOT MATCHED BY TARGET
     THEN INSERT(product, something) VALUES(S._product, S.something)
WHEN MATCHED 
     THEN UPDATE SET T.Something= S.Something
OUTPUT $action, Inserted.*, Deleted.*;
Run Code Online (Sandbox Code Playgroud)

此语句将根据需要插入或更新行,并返回被该OUTPUT子句插入或覆盖的值。


Ada*_*rad 5

使用合并操作。

MSDN 文档

根据与源表的连接结果对目标表执行插入、更新或删除操作。例如,您可以根据在另一个表中发现的差异,通过在一个表中插入、更新或删除行来同步两个表。