【问题标题】:SQL Merge not inserting new rowSQL合并不插入新行
【发布时间】:2018-05-21 10:37:16
【问题描述】:

我正在尝试使用 T-SQL Merge 检查记录是否存在并更新,如果不存在则插入。

更新工作正常,但插入不起作用。

我们将不胜感激地收到任何和所有这方面的帮助。

DECLARE
    @OperatorID          INT         = 2,
    @CurrentCalendarView VARCHAR(50) = 'month';

WITH CTE AS 
(
    SELECT * 
    FROM dbo.OperatorOption 
    WHERE OperatorID = @OperatorID
)
MERGE INTO OperatorOption AS T
USING CTE S ON T.OperatorID = S.OperatorID

WHEN MATCHED THEN 
   UPDATE 
       SET T.CurrentCalendarView = @CurrentCalendarView

WHEN NOT MATCHED BY TARGET THEN 
    INSERT (OperatorID, PrescriptionPrintingAccountID, CurrentCalendarView)
    VALUES (@OperatorID, NULL, @CurrentCalendarView);

【问题讨论】:

  • 看我的回答。您没有正确使用合并。您需要生成一个不匹配的行。它认为没有什么可插入的。

标签: sql sql-server tsql merge


【解决方案1】:

OperatorOption 中的一行已选择何时不存在于 OperatorOption 中?

如果您说此代码没有插入 - 您是对的,它没有插入,因为该行必须从那里开始(在这种情况下它不会插入),或者该行不存在开始,在这种情况下,源数据集中没有要插入的内容。

SELECT * 
FROM dbo.OperatorOption 
WHERE OperatorID = @OperatorID

返回什么?

这并不像你想象的那样工作。源 CTE 中没有任何内容。

“目标中缺少空白数据集”的答案是“否”,因此没有插入任何内容

要执行此操作,我使用以下构造:

INSERT INTO dbo.OperatorOption 
(OperatorID, PrescriptionPrintingAccountID, CurrentCalendarView)
SELECT @OperatorID, NULL, @CurrentCalendarView 
WHERE NOT EXISTS (
    SELECT * FROM dbo.OperatorOption 
    WHERE OperatorID = @OperatorID
    )

【讨论】:

  • 系统的新用户将不存在一行。
  • 当表中有与@OperatorID 匹配的值时,它会返回数据,这就是它进行更新的原因,但是当它不匹配时应该进行插入
  • 哦,我明白了,您使用的是WHEN NOT MATCHED BY TARGET。我以前从来没有这样用过
  • 我用这个只是为了看看它是否会起作用,WHEN NOT MATCHEDWHEN NOT MATCHED BY TARGET 都没有给出 0 行影响
  • MERGE 不是为此而构建的。您是在说'您在源代码中没有发现任何东西(源 CTE 中的内容)吗?答案是:不——源头没有遗漏任何东西。
【解决方案2】:

将值作为变量插入并不重要。它认为没有什么可插入的。

你需要产生不匹配的数据。

像这样:

DECLARE @OperatorID INT = 3, @CurrentCalendarView VARCHAR(50) = 'month';
declare @t table (operatorID int, CurrentCalendarView varchar(50));
insert into @t values (2, 'year');

MERGE @t AS TARGET
USING (SELECT @OperatorID, @CurrentCalendarView) AS source (operatorID, CurrentCalendarView)
   on (TARGET.operatorID = Source.operatorID)
WHEN MATCHED THEN 
   UPDATE SET TARGET.CurrentCalendarView = @CurrentCalendarView    
WHEN NOT MATCHED BY TARGET THEN 
    INSERT (OperatorID, CurrentCalendarView)
    VALUES (source.OperatorID, source.CurrentCalendarView);

select * from @t

【讨论】:

    【解决方案3】:

    插入可能不起作用,因为您的源 CTE 不生成任何行。根据您的表格的组织方式,您可能需要从其他来源中进行选择,或者使用table valued constructor 来生成源数据。

    【讨论】:

    • CTE 在更新工作时生成数据,但插入影响 0 行
    • CTE 不应该带回任何行,这就是我希望它进行插入的原因
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 2020-03-22
    • 1970-01-01
    • 2015-10-24
    相关资源
    最近更新 更多