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 语句错误的主要内容,如果未能解决你的问题,请参考以下文章

MERGE 语句错误

DB2 MERGE 语句错误

SQL 合并错误:MERGE 语句试图更新或删除 [重复]

过程包体中的 Oracle Merge 语句错误

SQL 错误:“嵌套的 INSERT、UPDATE、DELETE 或 MERGE 语句必须具有 OUTPUT 子句。” - 在 Azure Databricks 中执行时

IF EXISTS 和 MERGE 语句