如果存在,则进行MSSQL插入或更新

9
如果行不存在,则需要插入一行并更新行,我已经找到了MySQL的解决方案:
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE    

姓名="A",年龄=19

但我找不到MSSQL的类似方法。


1
你看过合并(Transact-SQL)了吗? - Thom A
那个语法是MySQL的怪癖。标准和更强大的方法是使用MERGE - Panagiotis Kanavos
2个回答

14
您可以按照以下顺序使用两个语句(INSERT+UPDATE)。如果它不存在,则更新不会更新任何内容,如果已经存在,则插入不会插入任何内容:
UPDATE T SET
    name = 'A',
    age = 19
FROM
    [table] AS T
WHERE
    T.id = 1

INSERT INTO [table] (
    id,
    name,
    age)
SELECT
    id = 1,
    name = 'A',
    age = 19
WHERE
    NOT EXISTS (SELECT 'not yet loaded' FROM [table] AS T WHERE T.id = 1)

或者使用MERGE

;WITH ValuesToMerge AS
(
    SELECT
        id = 1,
        name = 'A',
        age = 19
)
MERGE INTO 
    [table] AS T
USING
    ValuesToMerge AS V ON (T.id = V.id)
WHEN NOT MATCHED BY TARGET THEN
    INSERT (
        id,
        name,
        age)
    VALUES (
        V.id,
        V.name,
        V.age)
WHEN MATCHED THEN
    UPDATE SET
        name = V.name,
        age = V.name;

4

我更喜欢检查@@ROWCOUNT。这是一种更紧凑的解决方案。

UPDATE table set name = 'A', age = 19 WHERE id = 1;
IF @@ROWCOUNT = 0
INSERT INTO table (id, name, age) VALUES(1, "A", 19);

因为您直接在UPDATE子句中设置值,这可能会导致SQL注入的可能性。第二部分使用VALUES方法避免了这种情况。 - anakaine
1
这只是一个例子。在生产代码中,'A'将变成一个变量@a。 - Neil B
可能想要围绕它进行交易,并根据您遇到的更普遍的操作来交换UPDATE和INSERT。如果INSERT更频繁发生,请先进行INSERT测试。如果您经常更新现有行,请先进行UPDATE语句。 https://sqlperformance.com/2020/09/locking/upsert-anti-pattern - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接