MS SQL 相当于 ON DUPLICATE KEY UPDATE / UPSERT
MS SQL equivalent of ON DUPLICATE KEY UPDATE / UPSERT
我是 MS 的新手 postgres 用户 SQL。我需要复制 ON DUPLICATE KEY UPDATE 功能(有时称为 UPSERT)。我有 table 用户(此处已简化),包括年龄和性别。
使用此示例查询,但根据需要更改 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。
P.S。我在 Whosebug 的此处查看了 MSSQL 中的其他 UPSERT 问题。这就是我得到这种语法的方式。不过,我无法通过他们了解这里的问题。
将 table 合并到自身时,您将无法插入 table 中不存在的行:
我建议执行以下操作:
DECLARE @id INT = 222, @age int = 33, @sex VARCHAR(10) = 'M'
IF EXISTS (SELECT id FROM users WHERE id=@id)
BEGIN
UPDATE users SET age = @age, sex = @sex
END
ELSE
BEGIN
INSERT INTO users (id, age, sex) VALUES (@id, @age, @sex)
END
如果您从另一个应用程序调用它,您可能需要一个存储过程,因此您可能需要创建一个存储过程来执行此操作:
CREATE PROCEDURE sp_UpdateInsertUsers @id INT
, @age INT
, @sex VARCHAR(10)
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS
(SELECT id
FROM users
WHERE id = @id)
BEGIN
UPDATE users
SET age = @age, sex = @sex;
END;
ELSE
BEGIN
INSERT INTO users(id
, age
, sex)
VALUES
(@id
, @age
, @sex);
END;
END;
GO
像这样调用程序:
EXECUTE sp_UpdateInsertUsers @id = 222
, @age = 33
, @sex = 'M'
我最终使用了 this question 中的一些信息来解决它。它没有完全解决它,但它帮助我看到了我的 subselect (...) AS 源的问题。基本上,(显然)USING 隐含地假定源 table 并通过用 FROM users WHERE ...
明确指定它我阻止 sql 服务器检查它。无论如何,这是我最好的理解。
关键是,这个查询有效:运行 它一次,它插入一个新用户 (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')
;
ASP.NET 中带有绑定参数的示例,用于更新购物车中的产品:
MERGE
INTO [shoppingcart] WITH (holdlock) AS target
using (
SELECT @ProductID AS ProductID) AS source
ON (
target.productid = source.productid)
WHEN matched THEN
UPDATE
SET target.productid = source.productid,
target.quantity = target.quantity + 1,
target.date = @Date,
target.clientid = @ClientID
WHEN NOT matched THEN
INSERT
(
quantity,
date,
clientid,
productid
)
VALUES
(
@Quantity,
@Date,
@ClientID,
@ProductID
);
我是 MS 的新手 postgres 用户 SQL。我需要复制 ON DUPLICATE KEY UPDATE 功能(有时称为 UPSERT)。我有 table 用户(此处已简化),包括年龄和性别。
使用此示例查询,但根据需要更改 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。
P.S。我在 Whosebug 的此处查看了 MSSQL 中的其他 UPSERT 问题。这就是我得到这种语法的方式。不过,我无法通过他们了解这里的问题。
将 table 合并到自身时,您将无法插入 table 中不存在的行:
我建议执行以下操作:
DECLARE @id INT = 222, @age int = 33, @sex VARCHAR(10) = 'M'
IF EXISTS (SELECT id FROM users WHERE id=@id)
BEGIN
UPDATE users SET age = @age, sex = @sex
END
ELSE
BEGIN
INSERT INTO users (id, age, sex) VALUES (@id, @age, @sex)
END
如果您从另一个应用程序调用它,您可能需要一个存储过程,因此您可能需要创建一个存储过程来执行此操作:
CREATE PROCEDURE sp_UpdateInsertUsers @id INT
, @age INT
, @sex VARCHAR(10)
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS
(SELECT id
FROM users
WHERE id = @id)
BEGIN
UPDATE users
SET age = @age, sex = @sex;
END;
ELSE
BEGIN
INSERT INTO users(id
, age
, sex)
VALUES
(@id
, @age
, @sex);
END;
END;
GO
像这样调用程序:
EXECUTE sp_UpdateInsertUsers @id = 222
, @age = 33
, @sex = 'M'
我最终使用了 this question 中的一些信息来解决它。它没有完全解决它,但它帮助我看到了我的 subselect (...) AS 源的问题。基本上,(显然)USING 隐含地假定源 table 并通过用 FROM users WHERE ...
明确指定它我阻止 sql 服务器检查它。无论如何,这是我最好的理解。
关键是,这个查询有效:运行 它一次,它插入一个新用户 (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')
;
ASP.NET 中带有绑定参数的示例,用于更新购物车中的产品:
MERGE
INTO [shoppingcart] WITH (holdlock) AS target
using (
SELECT @ProductID AS ProductID) AS source
ON (
target.productid = source.productid)
WHEN matched THEN
UPDATE
SET target.productid = source.productid,
target.quantity = target.quantity + 1,
target.date = @Date,
target.clientid = @ClientID
WHEN NOT matched THEN
INSERT
(
quantity,
date,
clientid,
productid
)
VALUES
(
@Quantity,
@Date,
@ClientID,
@ProductID
);