MERGE 语句错误
Posted
技术标签:
【中文标题】MERGE 语句错误【英文标题】:MERGE Statement Error 【发布时间】:2013-12-06 15:30:52 【问题描述】:对原始问题的更新:
对我在做什么提供一些见解。我有一个标有[Staging].[HRIS_EEMaster]
的表,该表中包含有关员工、公司状态等的信息。我使用他们的个人身份证号码作为密钥[PersNo]
。我有一个我们最近添加的列,显示员工终止是自愿还是非自愿[Vol_Invol]
。似乎在某些时候,人力资源代表不小心,错过了将这个值添加到 4 名员工。我已尝试返回源以更正此信息,但时间已过,我现在无法编辑数据。
我想要做的是使用 [PersNo]
作为键更新 4 名员工的 [Vol_Invol]
字段。我需要一个更新脚本来查看[Staging].[HRIS_EEMaster]
,找到4 名员工的[PersNo]
,然后用“自愿”更新空白[Vol_Invol]
字段(这4 个都是自愿条款)。每个员工都有一个唯一的[PersNo]
。
我会将此脚本添加到现有的 SSIS 包中。这个 SSIS 包每月运行一次。暂存表被截断,然后加载新数据。还有一个带有 SCD 的包,它提供用于报告的主表。
我想将 UPDATE 脚本添加到 SQL 任务中,以便在每次提取数据时更新(更正)这 4 个空白。我对下面的代码执行了类似的操作,以更正错误删除的缺失成本中心。
我希望这会有所帮助,如果您需要更多信息,请告诉我。
原帖:
我正在编写一份人力资源报告,我必须更正 4 名缺少终止状态的员工。我之前曾使用以下声明来更正术语员工缺少成本中心的问题。
MERGE [Staging].[HRIS_EEMaster] AS tgt
USING (
SELECT PersNo AS EmpID,
Vol_Invol AS VIStat
FROM [dbo].[HRIS_MissingVol_Invol_Status]
) AS src ON src.EmpID = tgt.PersNo
WHEN NOT MATCHED BY TARGET
THEN INSERT (
PersNo,
Vol_Invol
)
VALUES (
src.EmpID,
src.VIStat
)
WHEN MATCHED
THEN UPDATE
SET tgt.PersNo = CASE
WHEN src.VIStat > '' THEN src.VIStat
ELSE tgt.Vol_Invol
END;
当我执行脚本时它返回一个错误:
Msg 245, Level 16, Stat 1, Line 1
Conversion failed when converting the nvarchar value 'Voluntary' to data type int.
我不确定它在说什么,因为我只是想将我创建的表中的“自愿”一词(请参阅上面的表名称脚本)到暂存表(也在上面)和列 [Vol_Invol]在两个表中都是 nvarchar(50)。
基本上我有 4 个人缺少所需的状态(无法再从源头更正的历史信息),我想运行此 MERGE 语句以用正确的值替换来自每月导出的空白。
此脚本将用作现有 SSIS 进程中的 SQL 任务。
【问题讨论】:
我不认为您试图将“自愿”一词放入Vol_Invol
列中 - 您正在尝试将其放入 PersNo
列中。
另外我会考虑只使用单独的插入和更新语句。 MERGE
is a hornet's nest waiting to jump on you.
@AaronBertrand,你能推荐一个更新声明吗?基本上,如果 PersNo = "12345" 那么我希望 Vol_Invol 是“自愿的”,否则,它需要是已经存在的任何东西。我之前做过更新,但只在同一列中。
无论在哪里已经存在?在源表还是目标表?如果两个表中都存在该列,则可以填充任何一个。
插入是否也需要考虑该条件,还是仅考虑更新?还是 INSERT 甚至是必要的,因为单词问题表明您正在使用所有这些代码来简单地更新 4 行?您能否解释一下何时要使用 VIStat 以及何时要使用 Vol_Invol?目前尚不清楚这些列中的任何一个是什么意思以及它们是如何相关的。请明确您的实际要求(并使用该信息更新问题)。
【参考方案1】:
看起来您正在尝试将 PersNo 设置为 VIStat...
SET tgt.PersNo = CASE
WHEN src.VIStat > '' THEN src.VIStat
【讨论】:
【参考方案2】:忘记MERGE
- it is a hornet's nest of issues,我实际上会重写我遇到的任何客户代码 (as do others)。为什么不只是:
BEGIN TRANSACTION;
UPDATE trg
SET trg.Vol_Invol = CASE
WHEN trg.PersNo = 12345 THEN 'Voluntary'
WHEN src.VIStat > '' THEN src.VIStat
ELSE trg.Vol_Invol END
FROM Staging.HRIS_EEMaster AS tgt
INNER JOIN dbo.HRIS_MissingVol_Invol_Status AS src
ON src.EmpID = tgt.PersNo;
INSERT Staging.HRIS_EEMaster(PersNo, Vol_Invol)
SELECT src.EmpID, src.VIStat
FROM dbo.HRIS_MissingVol_Invol_Status AS src
WHERE NOT EXISTS
(
SELECT 1 FROM Staging.HRIS_EEMaster
WHERE PersNo = src.EmpID
);
COMMIT TRANSACTION;
如果INSERT
需要考虑条件,则将该部分更改为:
INSERT Staging.HRIS_EEMaster(PersNo, Vol_Invol)
SELECT src.EmpID,
CASE WHEN src.EmpID = 12345 THEN 'Voluntary' ELSE src.VIStat END
但是我仍然对您的要求的几个方面感到完全困惑-您最终是如何得到MERGE
声明的,在阅读了您的单词问题后,我不知道...
【讨论】:
【参考方案3】:我使用了以下脚本。花了一点时间,但我让它工作了。
UPDATE [Staging].[HRIS_EEMaster]
SET [Vol_Invol] = CASE [PersNo]
WHEN '2000602' THEN 'Voluntary'
WHEN '2050004' THEN 'Voluntary'
WHEN '2050234' THEN 'Voluntary'
WHEN '2050746' THEN 'Voluntary'
ELSE [Vol_Invol]
END
如果有人有更好的脚本,请告诉我。
【讨论】:
以上是关于MERGE 语句错误的主要内容,如果未能解决你的问题,请参考以下文章
SQL 错误:“嵌套的 INSERT、UPDATE、DELETE 或 MERGE 语句必须具有 OUTPUT 子句。” - 在 Azure Databricks 中执行时