【发布时间】:2012-08-20 12:07:56
【问题描述】:
我正在尝试使用 T-Sql 中的 Merge 语句构建优化的渐变维度。我编写了以下代码来处理 SCD1 和 SCD2 更改,以及数据表中的正常插入,数据来自源表,Name 和 Age 是 SCD1 列,Animal 和 Blood 是 SCD2 列:
DECLARE @LoadingDate DATETIME
SET @LoadingDate = '2012-08-20 14:23:29.827'
--Handle SCD1 Changes
MERGE INTO Table_2 AS DIM
USING SourceTable AS SRC
ON (DIM.ID1 = SRC.ID1
AND DIM.ID2 = SRC.ID2)
WHEN MATCHED
AND (DIM.Name <> SRC.Name
OR DIM.AGE <> SRC.AGE)
THEN
UPDATE
SET DIM.Name = SRC.Name,
DIM.Age = SRC.Age;
--Handle SCD2 Changes
INSERT INTO Table_2
(ID1, ID2, --Business Key
Name, Age, --SCD1 Columns
Animal, Blood, --SCD2 Columns
DateEffective, DateExpires)
SELECT
ID1, ID2, --Business Key
Name, Age, --SCD1 Columns
Animal, Blood, --SCD2 Columns
DateEffective, DateExpires
FROM (
MERGE Table_2 AS DIM
USING SourceTable AS SRC
ON (DIM.ID1 = SRC.ID1
AND DIM.ID2 = SRC.ID2)
WHEN NOT MATCHED
THEN INSERT VALUES
(SRC.ID1, SRC.ID2,
SRC.Name, SRC.Age,
SRC.Animal, SRC.Blood,
@LoadingDate, NULL)
WHEN MATCHED
AND DIM.DateExpires IS NULL
AND (DIM.Animal != SRC.Animal
OR DIM.Blood != SRC.Blood)
THEN UPDATE SET DIM.DateExpires = @LoadingDate
OUTPUT $action Action_Out,
SRC.ID1, SRC.ID2,
SRC.Name, SRC.Age,
SRC.Animal, SRC.Blood,
@LoadingDate AS DateEffective,
NULL AS DateExpires) AS MERGE_OUT
WHERE MERGE_OUT.Action_Out = 'UPDATE';
该代码适用于 SCD1 更改(代码的第一部分),但它给了我错误: 尝试插入新行时出现错误,该行的业务键 ID1 和 ID2 与数据表中的任何其他行都不匹配,并且“Labus”是名称字段中的值。
两个表的设计如下图所示,但 SourceTable 没有管理列:
我真的很感激一些帮助。 谢谢!
【问题讨论】:
-
@Johan:我认为您不能将可为空的列设计为 SQL Server 中的标识列。所以 ID1 和 ID2 不能自动递增。其中一种 nvarchar 数据类型被隐式转换为 int,这是导致此问题的原因。
-
删除插入并让选择显示。确保您具有所需的 ID1、ID2 和名称的值。
-
如果我删除插入,我得到错误:消息 10729,级别 15,状态 1,第 30 行嵌套的 INSERT、UPDATE、DELETE 或 MERGE 语句不允许在不是的 SELECT 语句中INSERT 语句的直接行源。
标签: sql-server tsql ssis