与 UPSERT 合并,不在 table 中插入任何值

MERGE with UPSERT, not inserting any value in table

Table结构:

CREATE TABLE [dbo].[LockOfferByOfferUses](
[OfferID] [int] NULL,
[OfferCode] [varchar](50) NULL,
[LockCounter] [int] NULL,
[UpdatedDate] [datetime] NULL
) ON [PRIMARY]

SQL声明:

merge into LockOfferByOfferUses as Target
using (Select * from LockOfferByOfferUses Where OfferID=123 And OfferCode='abc' ) as Source
on Target.OfferID = Source.OfferID
when NOT MATCHED then
INSERT (OfferID,OfferCode,LockCounter,UpdatedDate) VALUES (123,'abc',1,GETDATE())
when MATCHED then 
update set Target.LockCounter=Target.LockCounter+1;

我想做的是,通过 offerID 检查 "LockOfferByOfferUse" 中是否存在记录。如果不存在,则插入一条记录;如果存在更新 "LockCounter" 列。

更新部分有效,但插入无效。它显示消息“(0 行受影响)”。没有错误信息。

非常感谢您的帮助。

由于您的 "Source" table 是空的,因此没有任何内容可以匹配目标,因此不会插入任何内容。如果要插入数据,源 table 必须包含要插入的行。

更新: 关于您的评论:实际上有两个不同的 WHEN NOT MATCHED 子句:WHEN NOT MATCHED BY TARGETWHEN NOT MATCHED BY SOURCE。但是您只能为 WHEN NOT MATCHED BY TARGET 子句(这似乎是默认子句)插入值。但是因为你没有任何源数据,所以没有什么可以插入的。

源应该是您要使用的数据 - 而不是针对目标的另一个查询 table。

所以它应该是这样的:

merge into LockOfferByOfferUses as Target
using (VALUES(123)) as Source (OfferID)
on Target.OfferID = Source.OfferID
when NOT MATCHED then
INSERT (OfferID,OfferCode,LockCounter,UpdatedDate) VALUES (Source.OfferID,'abc',1,GETDATE())
when MATCHED then 
update set Target.LockCounter=Target.LockCounter+1;

(这取决于您将其他值也向上移动到 Source 中,或者只是将它们作为 INSERT 中的文字 - 对于更复杂的查询,更多的值可能也需要在多个地方)。

让我们评论您的查询以了解发生了什么:

作为目标合并到 LockOfferByOfferUses

merge into LockOfferByOfferUses as Target

源查询数据,只过滤offerId=123

using (Select * from LockOfferByOfferUses Where OfferID=123 And OfferCode='abc' ) as Source

进行合并的条件

on Target.OfferID = Source.OfferID

当我们有一行 ID 不存在于目标中时,我们插入新数据

when NOT MATCHED then
INSERT (OfferID,OfferCode,LockCounter,UpdatedDate) VALUES (123,'abc',1,GETDATE())

如果我们有匹配的数据,我们会更新

when MATCHED then 
update set Target.LockCounter=Target.LockCounter+1;

因此发生的事情是来自源 table 的所有 ID 都存在于目标 table 中,无需插入新行,罪魁祸首是:

OfferID=123

您总是在查询相同的值,因此我假设您的目标中有 OfferId 为 123 的商品。

更正查询:

merge into LockOfferByOfferUses as Target
using (Select * from LockOfferByOfferUses Where OfferCode='abc' ) as Source
on Target.OfferID = Source.OfferID
when NOT MATCHED then
INSERT (OfferID,OfferCode,LockCounter,UpdatedDate) VALUES (123,'abc',1,GETDATE())
when MATCHED then 
update set Target.LockCounter=Target.LockCounter+1;

使用此查询,您将合并目标 table.

中尚未存在的具有 OfferCode abc 的所有元素