sql - MS SQL 相当于 ON DUPLICATE KEY UPDATE/UPSERT

标签 sql sql-server upsert on-duplicate-key

我是一名刚接触 MS SQL 的 postgres 用户。我需要复制 ON DUPLICATE KEY UPDATE 功能(有时称为 UPSERT)。我有一张包含年龄和性别的用户表(此处已简化)。

使用此示例查询,但根据需要更改 id,UPDATE 功能有效,但 INSERT 无效。没有错误,它只是说 0 行受影响。

MERGE
    users AS target 
USING
    (SELECT id FROM users WHERE id=222) AS source
ON
    target.id = source.id

WHEN MATCHED THEN 
    UPDATE SET 
        target.id  = source.id,
        target.age = 33,
        target.sex = 'M'

WHEN NOT MATCHED THEN 
    INSERT (id, age, sex) VALUES (222, 33, 'M')
;

如果重要(也许有更简单的方法),我在 linux 中使用 python3。

附言我查看了 StackOverflow 中的其他 UPSERT in MSSQL 问题。这就是我得到这种语法的方式。不过,我无法通过他们理解这里的问题。

最佳答案

我最终使用了来自 this question 的一些信息解决它。它没有完全解决它,但它帮助我看到了我的 subselect (...) AS 源的问题。基本上,(显然)USING 隐式假定源表并通过使用 FROM users WHERE ... 显式指定它,我阻止了 sql server 检查它。无论如何,这是我最好的理解。

重点是,这个查询有效:运行一次,它会插入一个带有 (555, 55, 'M') 的新用户。再次运行它,相同的记录更新为 (555, 22, 'F')

此外,显然 MERGE 可能会在高速率下出现并发问题,因此链接的问题建议使用 HOLDLOCK,我在这里有。

MERGE INTO users WITH (HOLDLOCK) AS target
    USING 
        (SELECT 555 AS id) AS source 
ON 
    (target.id = source.id)

WHEN MATCHED THEN 
        UPDATE SET 
            target.id  = source.id,
            target.age = 22,
            target.sex = 'F'
WHEN NOT MATCHED THEN 
        INSERT (id, age, sex) VALUES (555, 55, 'M')
;

关于sql - MS SQL 相当于 ON DUPLICATE KEY UPDATE/UPSERT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41882471/

相关文章:

sql - 如何创建此查询

sql - 使用 powershell 为单个事务中的多个文件调用 sqlcmd

sql - 使用条件设置行安全性

sql - 我想转表

node.js - 简单 mongo/monk findAndModify 查询的问题

mysql - 结果差异(MySQL 5.7 与 MySQL 8.0)

sql - 重叠日期范围(SQL Server 2008)按天分组的最有效方法是什么?

postgresql - UPSERT 测试代码中的语法错误

postgresql - Postgres UPSERT语法困惑

SQLite 相当于 PostgreSQL 的 GREATEST 函数