Chr*_*mer 4 sql sql-server merge ssis etl
我对这个说法感到惊讶MERGE,该公司并没有真正实现第 2 类缓慢变化维度,但已经接近了。奇怪的是,它甚至不是分析数据,但让我们忽略这个可怕的决定。我有这个工作引用指示HashBytes的已更改行。INSERT不幸的是,为了解决所有场景,我最终在临时表的末尾 添加了实际上保存更新行的附加内容。
唉,它很实用,但如果您有更有效的设计,请分享。我会很感激。
但是,我试图row count不仅INSERT从Temp表中获取代表,而且还代表更新和新的INSERTS,所有这些都是具有自己的不同单独的操作row count,我需要记录和解释。
请问我该怎么做?
DECLARE @dtNow AS DATETIME = GetDate()
DECLARE @dtPast AS DATETIME = DATEADD(day,-1,GetDate())
DECLARE @dtFuture AS DATETIME = '22991231'
SET NOCOUNT ON;
-- Temp Table is JUST Updating Rows reflecting
--Historical Marker on existing row No content change to row's columnar content data
IF OBJECT_ID('tempdb..#TheTempTableName') IS NOT NULL DROP TABLE #TheTempTableName
CREATE TABLE #TheTempTableName
(
ABunchOfColumns
RowCreatedDate datetime NULL,
RowEffectiveDate datetime NULL,
RowTerminationDate datetime NULL,
RowIsCurrent bit NULL,
RowHash varchar(max) NULL,
)
INSERT INTO #TheTempTableName
(
ABunchOfColumns
,RowCreatedDate
,RowEffectiveDate
,RowTerminationDate
,RowIsCurrent
,RowHash
)
SELECT
ABunchOfColumns
,RowCreatedDate
,RowEffectiveDate
,RowTerminationDate
,RowIsCurrent
,RowHash
FROM
(
MERGE tblDim WITH (HOLDLOCK) AS target
USING
(
SELECT
ABunchOfColumns
,RowCreatedDate
,RowEffectiveDate
,RowTerminationDate
,RowIsCurrent
,RowHash
FROM dbo.tblStaging
)
AS source
ON target.PKID = source.PKID
WHEN MATCHED
AND target.RowIsCurrent = 1
AND target.RowHash != source.RowHash
------- PROCESS ONE -- UPDATE --- HISTORICALLY MARK EXISTING ROWS
THEN UPDATE SET
RowEffectiveDate = @dtPast
,RowTerminationDate = @dtPast
,RowIsCurrent = 0
----- PROCESS TWO -- INSERT ---INSERT NEW ROWS
WHEN NOT MATCHED
THEN INSERT --- THIS INSERT Goes directly into Target ( DIM ) Table (New Rows not matched with PK = PK )
(
ABunchOfColumns
,RowCreatedDate
,RowEffectiveDate
,RowTerminationDate
,RowIsCurrent
,RowHash
)
VALUES
(
source.ABunchOfColumns
,@dtNow --source.RowCreatedDate,
,@dtFuture ---source.RowEffectiveDate,
,@dtFuture ---source.RowTerminationDate,
,1 ---source.RowIsCurrent,
,source.RowHash
)
-------PROCESS THREE a -- INSERT ---OUTPUT MATCHED ROWS FROM PROCESS ONE THAT CAUSED HISTORICAL MARK (CHANGES) "INSERT"
OUTPUT
$action Action_Out,
ABunchOfColumns
,RowCreatedDate
,RowEffectiveDate
,RowTerminationDate
,RowIsCurrent
,RowHash
)
AS MERGE_OUT
WHERE MERGE_OUT.Action_Out = 'UPDATE';
----------PROCESS THREE b -- INSERT FROM Temp Tbl to final
--Now we flush the data in the temp table into dim table
INSERT INTO tblDim
(
ABunchOfColumns
,RowCreatedDate
,RowEffectiveDate
,RowTerminationDate
,RowIsCurrent
,RowHash
)
SELECT
ABunchOfColumns
,@dtNow AS RowCreatedDate
,@dtFuture AS RowEffectiveDate
,@dtFuture AS RowTerminationDate
,1 AS RowIsCurrent
,RowHash
FROM #TheTempTableName
END
Run Code Online (Sandbox Code Playgroud)
有两种类型的删除 (1) 实际删除 (2) 主键更新。所以你也可以说有两种类型的插入(1)真正的插入(2)主键更新更新总是更新。
接下来的困境是插入/删除组合何时才是真正的更新。
通常,如果您并不真正关心上面的内容,像这样的简单合并就足够了
MERGE esqlProductTarget T
USING esqlProductSource S
ON (S.ProductID = T.ProductID)
WHEN MATCHED
THEN UPDATE
SET T.Name = S.Name,
T.ProductNumber = S.ProductNumber,
T.Color = S.Color
WHEN NOT MATCHED BY TARGET
THEN INSERT (ProductID, Name, ProductNumber, Color)
VALUES (S.ProductID, S.Name, S.ProductNumber, S.Color)
WHEN NOT MATCHED BY SOURCE
THEN DELETE
OUTPUT S.ProductID, $action into @MergeLog;
SELECT MergeAction, Cnt=count(*)
FROM @MergeLog
GROUP BY MergeAction
Run Code Online (Sandbox Code Playgroud)
输出将类似于:
+-------------+-----+--+
| MergeAction | Cnt | |
+-------------+-----+--+
| DELETE | 100 | |
| UPDATE | 60 | |
| INSERT | 70 | |
+-------------+-----+--+
Run Code Online (Sandbox Code Playgroud)
参考https://www.essentialsql.com/introduction-merge-statement/
我不确定为什么你有“WHERE MERGE_OUT.Action_Out = 'UPDATE'。但是如果你删除它,那么你可以获得你的行数。除非我误解了你的查询。