从合并中捕获插入、更新和删除计数
Capturing Insert ,Update and Delete counts from Merge
我使用下面的 T-SQL Merge 语句将事务数据库中的数据增量加载到数据仓库中。此 Merge 语句将数据加载为 SCD 类型 2,并且运行良好。
--Begin handling SCD2 changes
INSERT INTO [DWDB].[dbo].[Dim_Warehouse]
(
stg.[WarehouseID]
,stg.[WarehouseCode]
,stg.[WarehouseName]
)
SELECT
MERGE_OUT.[WarehouseID]
,MERGE_OUT.[WarehouseCode]
,MERGE_OUT.[WarehouseName]
FROM
(
MERGE [DWDB].[dbo].[Dim_Warehouse] AS stg
USING SourceDB.dbo.Warehouse AS SRC
ON (stg.WarehouseID = SRC.WarehouseID)
WHEN NOT MATCHED
THEN INSERT VALUES
(
SRC.[WarehouseID]
,SRC.[WarehouseCode]
,SRC.[WarehouseName]
)
WHEN MATCHED
AND stg.dw_EndDate IS NULL
AND
(
stg.[WarehouseName] <> src.[WarehouseName]
)
THEN
UPDATE
SET stg.dw_EndDate = GETDATE()
,stg.dw_IsCurrent = 0
OUTPUT $action Action_Out
,SRC.[WarehouseID]
,SRC.[WarehouseCode]
,SRC.[WarehouseName]
) AS MERGE_OUT
WHERE MERGE_OUT.Action_Out = 'UPDATE';
(为了简单起见,从上面的源代码中删除了一些列)
我最后的工作是依靠MERGE语句来知道有多少条记录被插入、更新、删除但没有成功。
我已尝试创建一个临时文件 table 并按照这些链接的建议将列放入输出中:Sql Server 2008 MERGE - best way to get counts
和
https://www.purplefrogsystems.com/blog/2012/01/using-t-sql-merge-to-load-data-warehouse-dimensions/
但它看起来与我的情况不同。
非常感谢您的帮助。
为了使术语正确,@archive
是一个 table 变量,而不是临时变量 table。 (它们在很多方面都不同)。临时 table 看起来像这样 #archive
要解决您的问题,您只需照常加载到 table 变量,然后从该 table 变量插入。这个 activity 分两步。不需要一步到位。
另外仅供参考,根本没有必要使用合并,您可以使用单独的 insert/update 语句。很多人没有意识到这一点。还要记住 merge
的问题列表。它们大多是边缘情况,但请记住还有其他选择
https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/
-- Create the table variable to capture the output
DECLARE @MergeOutput (
Action_Out VARCHAR(100),
[WarehouseID] INT,
[WarehouseCode] VARCHAR(50),
[WarehouseName] VARCHAR(50)
);
-- mere into table, capturing output into table variable
MERGE [DWDB].[dbo].[Dim_Warehouse] AS stg
USING SourceDB.dbo.Warehouse AS SRC
ON (stg.WarehouseID = SRC.WarehouseID)
WHEN NOT MATCHED
THEN INSERT VALUES
(
SRC.[WarehouseID]
,SRC.[WarehouseCode]
,SRC.[WarehouseName]
)
WHEN MATCHED
AND stg.dw_EndDate IS NULL
AND
(
stg.[WarehouseName] <> src.[WarehouseName]
)
THEN
UPDATE
SET stg.dw_EndDate = GETDATE()
,stg.dw_IsCurrent = 0
OUTPUT $action Action_Out
,SRC.[WarehouseID]
,SRC.[WarehouseCode]
,SRC.[WarehouseName]
INTO @MergeOutput
-- Perform insert based on table variable
INSERT INTO [DWDB].[dbo].[Dim_Warehouse]
(
[WarehouseID]
,[WarehouseCode]
,[WarehouseName]
)
SELECT
[WarehouseID]
,[WarehouseCode]
,[WarehouseName]
FROM @MergeOutput
WHERE Action_Out = 'UPDATE';
我使用下面的 T-SQL Merge 语句将事务数据库中的数据增量加载到数据仓库中。此 Merge 语句将数据加载为 SCD 类型 2,并且运行良好。
--Begin handling SCD2 changes
INSERT INTO [DWDB].[dbo].[Dim_Warehouse]
(
stg.[WarehouseID]
,stg.[WarehouseCode]
,stg.[WarehouseName]
)
SELECT
MERGE_OUT.[WarehouseID]
,MERGE_OUT.[WarehouseCode]
,MERGE_OUT.[WarehouseName]
FROM
(
MERGE [DWDB].[dbo].[Dim_Warehouse] AS stg
USING SourceDB.dbo.Warehouse AS SRC
ON (stg.WarehouseID = SRC.WarehouseID)
WHEN NOT MATCHED
THEN INSERT VALUES
(
SRC.[WarehouseID]
,SRC.[WarehouseCode]
,SRC.[WarehouseName]
)
WHEN MATCHED
AND stg.dw_EndDate IS NULL
AND
(
stg.[WarehouseName] <> src.[WarehouseName]
)
THEN
UPDATE
SET stg.dw_EndDate = GETDATE()
,stg.dw_IsCurrent = 0
OUTPUT $action Action_Out
,SRC.[WarehouseID]
,SRC.[WarehouseCode]
,SRC.[WarehouseName]
) AS MERGE_OUT
WHERE MERGE_OUT.Action_Out = 'UPDATE';
(为了简单起见,从上面的源代码中删除了一些列)
我最后的工作是依靠MERGE语句来知道有多少条记录被插入、更新、删除但没有成功。
我已尝试创建一个临时文件 table 并按照这些链接的建议将列放入输出中:Sql Server 2008 MERGE - best way to get counts 和 https://www.purplefrogsystems.com/blog/2012/01/using-t-sql-merge-to-load-data-warehouse-dimensions/ 但它看起来与我的情况不同。
非常感谢您的帮助。
为了使术语正确,@archive
是一个 table 变量,而不是临时变量 table。 (它们在很多方面都不同)。临时 table 看起来像这样 #archive
要解决您的问题,您只需照常加载到 table 变量,然后从该 table 变量插入。这个 activity 分两步。不需要一步到位。
另外仅供参考,根本没有必要使用合并,您可以使用单独的 insert/update 语句。很多人没有意识到这一点。还要记住 merge
的问题列表。它们大多是边缘情况,但请记住还有其他选择
https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/
-- Create the table variable to capture the output
DECLARE @MergeOutput (
Action_Out VARCHAR(100),
[WarehouseID] INT,
[WarehouseCode] VARCHAR(50),
[WarehouseName] VARCHAR(50)
);
-- mere into table, capturing output into table variable
MERGE [DWDB].[dbo].[Dim_Warehouse] AS stg
USING SourceDB.dbo.Warehouse AS SRC
ON (stg.WarehouseID = SRC.WarehouseID)
WHEN NOT MATCHED
THEN INSERT VALUES
(
SRC.[WarehouseID]
,SRC.[WarehouseCode]
,SRC.[WarehouseName]
)
WHEN MATCHED
AND stg.dw_EndDate IS NULL
AND
(
stg.[WarehouseName] <> src.[WarehouseName]
)
THEN
UPDATE
SET stg.dw_EndDate = GETDATE()
,stg.dw_IsCurrent = 0
OUTPUT $action Action_Out
,SRC.[WarehouseID]
,SRC.[WarehouseCode]
,SRC.[WarehouseName]
INTO @MergeOutput
-- Perform insert based on table variable
INSERT INTO [DWDB].[dbo].[Dim_Warehouse]
(
[WarehouseID]
,[WarehouseCode]
,[WarehouseName]
)
SELECT
[WarehouseID]
,[WarehouseCode]
,[WarehouseName]
FROM @MergeOutput
WHERE Action_Out = 'UPDATE';