我有一个带有以下查询的存储过程在SQL Server中使用MERGE插入/更新,但查询可以正常进行更新,但它不适用于Insert。 虽然我在Target中获得了正确的更新记录但是对于新插入,它失败了。 基本上,我有4个表.SUPPORT_STAFF_BAK是需要从源表UNIQUE_DUP_TEST更新的目标表,基于来自我尝试使用连接实现的其他两个表(REF_FUNCTION,DATA_PERIOD)的几个条件。 根据条件,我们需要检查目标,如果当前data_period存在相同的ggid,我们需要更新它,否则我们需要根据条件再次插入新记录。
MERGE SUPPORT_STAFF_BAK AS SUPP_STAFF
USING
(SELECT G_UNIQUE.[GLOBAL_ID],
G_UNIQUE.[FIRST_NAME],
G_UNIQUE.[LAST_NAME],
G_UNIQUE.[EMAIL],
G_UNIQUE.[Gender],
G_UNIQUE.[DATE_OF_BIRTH],
G_UNIQUE.[PRODUCTION_UNIT_CODE],
ORG.[LEGAL_ENTITY_COUNTRY_CODE],
ORG.[LEGAL_ENTITY_COUNTRY],
G_UNIQUE.[JOB_NAME],
ORG.[BU_CODE],
ORG.[BU_NAME],
ORG.[SBU_CODE],
ORG.[SBU_NAME],
G_UNIQUE.[GRADE_LETTER],
CASE
WHEN G_UNIQUE.[EMPLOYEE_STATUS] = 'A' THEN 'Active'
WHEN G_UNIQUE.[EMPLOYEE_STATUS] = 'S' THEN 'Suspended'
WHEN G_UNIQUE.[EMPLOYEE_STATUS]= 'T' THEN 'Terminated'
END AS [EMPLOYEE_STATUS],
CASE WHEN G_UNIQUE.[CATEGORY] = 'DSS' THEN G_UNIQUE.[CATEGORY_DETAIL] ELSE ''
END AS [CATEGORY],
G_UNIQUE.[CATEGORY_DETAIL],
G_UNIQUE.[FIRST_JOINING_DATE],
PERIOD.DATA_PERIOD_ID
FROM UNIQUE_DUP_TEST G_UNIQUE
INNER JOIN GDH_ORG ORG
ON G_UNIQUE.PRODUCTION_UNIT_CODE=ORG.PRODUCTION_UNIT_CODE
INNER JOIN REF_FUNCTION FUNC
ON G_UNIQUE.CATEGORY_DETAIL=FUNC.FUNCTION_CODE
INNER JOIN DATA_PERIOD PERIOD
ON FUNC.FUNCTION_ID=PERIOD.FUNCTION_ID
WHERE PERIOD.DATA_YEAR=YEAR(GETDATE()) AND PERIOD.DATA_MONTH=MONTH(GETDATE())
) AS G_SOURCE
ON SUPP_STAFF.GGID = G_SOURCE.GLOBAL_ID AND SUPP_STAFF.PRODUCTION_UNIT_CODE=G_SOURCE.PRODUCTION_UNIT_CODE
AND SUPP_STAFF.DATA_PERIOD_ID=G_SOURCE.DATA_PERIOD_ID
WHEN MATCHED THEN
UPDATE SET
[SUPP_STAFF].[FIRST_NAME] = G_SOURCE.[FIRST_NAME],
[SUPP_STAFF].[LAST_NAME] = G_SOURCE.[LAST_NAME],
[SUPP_STAFF].[EMAIL] = G_SOURCE.[EMAIL],
[SUPP_STAFF].[GENDER] = G_SOURCE.[Gender],
[SUPP_STAFF].[DATE_OF_BIRTH] = G_SOURCE.[DATE_OF_BIRTH],
[SUPP_STAFF].[LEGAL_ENTITY_COUNTRY_CODE] = G_SOURCE.[LEGAL_ENTITY_COUNTRY_CODE],
[SUPP_STAFF].[LEGAL_ENTITY_COUNTRY_NAME] = G_SOURCE.[LEGAL_ENTITY_COUNTRY],
[SUPP_STAFF].[GCM_ROLE] = G_SOURCE.[JOB_NAME],
[SUPP_STAFF].[BU_CODE] = G_SOURCE.[BU_CODE],
[SUPP_STAFF].[BU_NAME] = G_SOURCE.[BU_NAME],
[SUPP_STAFF].[SBU_CODE] = G_SOURCE.[SBU_CODE],
[SUPP_STAFF].[SBU_NAME] = G_SOURCE.[SBU_NAME],
[SUPP_STAFF].[GRADE] = G_SOURCE.[GRADE_LETTER],
[SUPP_STAFF].[EMPLOYEE_STATUS] = G_SOURCE.[EMPLOYEE_STATUS],
[SUPP_STAFF].[EMPLOYEE_CATEGORY] = G_SOURCE.[CATEGORY],
[SUPP_STAFF].[START_DATE] = G_SOURCE.[FIRST_JOINING_DATE],
[SUPP_STAFF].[UPDATE_DATE] = GETDATE(),
[SUPP_STAFF].[UPDATE_USER] = CASE WHEN G_SOURCE.[EMPLOYEE_STATUS]='Terminated' THEN 'Delete'
WHEN G_SOURCE.[EMPLOYEE_STATUS]<>'Terminated' THEN 'Update'
END,
[SUPP_STAFF].[SUPPORT_STAFF_FUNCTION] = CASE WHEN G_SOURCE.[EMPLOYEE_STATUS]='Terminated' THEN NULL
WHEN G_SOURCE.[EMPLOYEE_STATUS]<>'Terminated' THEN G_SOURCE.[CATEGORY_DETAIL]
END
WHEN NOT MATCHED AND G_SOURCE.[CATEGORY] = 'CC1'
AND G_SOURCE.[EMPLOYEE_STATUS] IN ('A, S')
THEN
INSERT( [GGID],
[FIRST_NAME],
[LAST_NAME],
[EMAIL],
[GENDER],
[DATE_OF_BIRTH],
[LEGAL_ENTITY_COUNTRY_CODE],
[LEGAL_ENTITY_COUNTRY_NAME],
[GCM_ROLE],
[BU_CODE],
[BU_NAME],
[SBU_CODE],
[SBU_NAME],
[GRADE],
[EMPLOYEE_STATUS],
[EMPLOYEE_CATEGORY],
[START_DATE],
[UPDATE_DATE],
[UPDATE_USER],
[SUPPORT_STAFF_FUNCTION]
)
VALUES (
G_SOURCE.[GLOBAL_ID],
G_SOURCE.[FIRST_NAME],
G_SOURCE.[LAST_NAME],
G_SOURCE.[EMAIL],
G_SOURCE.[Gender],
G_SOURCE.[DATE_OF_BIRTH],
G_SOURCE.[LEGAL_ENTITY_COUNTRY_CODE],
G_SOURCE.[LEGAL_ENTITY_COUNTRY],
G_SOURCE.[JOB_NAME],
G_SOURCE.[BU_CODE],
G_SOURCE.[BU_NAME],
G_SOURCE.[SBU_CODE],
G_SOURCE.[SBU_NAME],
G_SOURCE.[GRADE_LETTER],
G_SOURCE.[EMPLOYEE_STATUS],
G_SOURCE.[CATEGORY_DETAIL],
G_SOURCE.[FIRST_JOINING_DATE],
GETDATE(),
'Insert',
G_SOURCE.[CATEGORY_DETAIL]
)
OUTPUT $action,
INSERTED.GGID作为GGID; SELECT @@ ROWCOUNT;
答案 0 :(得分:0)
你的一个假设是错误的。源查询的行数少于您的想法,或者存在匹配项,或者不满足插入条件。否则查询就可以了。
要调试这个,我会将源查询插入临时表并手动检查其内容,以确保它们符合您的期望。
然后,您可以加入目标,看看您的插入内容是否可以转换为更新(例如select * from Source join Target on ...
)。在内部,MERGE
只是一个完整的外连接,你可以手动重现。
现在没人能告诉你确切的答案。您需要自己调试并检查数据。
答案 1 :(得分:0)
最后我发现了错误。错误发生在以下2个地方 -
CASE WHEN G_UNIQUE.[CATEGORY] = 'DSS' THEN G_UNIQUE.[CATEGORY_DETAIL] ELSE '' END AS [CATEGORY],
我用
替换了它CASE WHEN G_UNIQUE.[CATEGORY] = 'DSS' THEN G_UNIQUE.[CATEGORY_DETAIL] ELSE ''
END AS [EMPLOYEE_FUNCTION],
此外,我在Source查询中又添加了一个列 -
G_UNIQUE.[CATEGORY],
此外,下面有错误的代码
WHEN NOT MATCHED AND G_SOURCE.[CATEGORY] = 'CC1'
AND G_SOURCE.[EMPLOYEE_STATUS] IN ('A, S')
被以下正确的代码替换 -
WHEN NOT MATCHED AND G_SOURCE.[CATEGORY] = 'CC1'
AND G_SOURCE.[EMPLOYEE_STATUS] IN ('Active', 'Suspended')
实际上,我缺少1个源列,并且在插入时检查了相同的值,因此插入失败了。 此外,在Employee_status的源代码中,我将值检查为A,S和T,然后将它们替换为Active,Suspended,Terminated但在插入时不匹配时,我每次都检查A,S,T的值返回错误,因此插入失败。