-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMerge-CDC-NotEqual-HardDelete.sql
More file actions
148 lines (126 loc) · 2.87 KB
/
Merge-CDC-NotEqual-HardDelete.sql
File metadata and controls
148 lines (126 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* Run once
IF OBJECT_ID('tempdb.dbo.#source') IS NOT NULL DROP TABLE #source;
IF OBJECT_ID('tempdb.dbo.#target') IS NOT NULL DROP TABLE #target;
IF OBJECT_ID('tempdb.dbo.#debug') IS NOT NULL DROP TABLE #debug;
-- Conditions:
-- 1) Source data is not SCD2
-- 2) Target data is not SCD2
-- 3) Use NOT EQUAL comparison for Change Data Capture
-- 4) Physically delete target rows not in source
CREATE TABLE #source
( SK INT IDENTITY(1,1)
, FirstName VARCHAR(20)
, LastName VARCHAR(30)
, EmailAddress VARCHAR(50)
)
CREATE TABLE #target
( SK INT
, FirstName VARCHAR(20)
, LastName VARCHAR(30)
, EmailAddress VARCHAR(50)
, Status CHAR(1)
)
CREATE TABLE #debug
( ACTION CHAR(6)
, SK INT
, FirstName VARCHAR(20)
, LastName VARCHAR(30)
, EmailAddress VARCHAR(50)
)
INSERT INTO #source
(FirstName,LastName,EmailAddress)
VALUES
('John','Doe','john.doe@foo.com')
,('Mary','Jones','mary.jones@bar.com')
,('Joe','Bloggs','joe@bloggs.com')
*/
-- Create code as a SP for easy reuse
DROP PROCEDURE deleteme
GO
CREATE PROCEDURE deleteme
AS
BEGIN
TRUNCATE TABLE #debug
INSERT INTO #debug
SELECT
ACTION
,SK
,FirstName
,LastName
,EmailAddress
FROM (
MERGE #target tgt
USING #source src
ON (tgt.SK = src.SK)
-- New Rows
WHEN NOT MATCHED
THEN INSERT
(
SK
,FirstName
,LastName
,EmailAddress
,Status
)
VALUES (
src.SK
,src.FirstName
,src.LastName
,src.EmailAddress
,'I'
)
-- Changed Rows
-- Use NOT EQUAL comparison to detect actual changes
WHEN MATCHED
AND (
(tgt.FirstName <> src.FirstName)
OR (tgt.LastName <> src.LastName)
OR (tgt.EmailAddress <> src.EmailAddress)
)
THEN UPDATE
SET tgt.FirstName = src.FirstName
,tgt.LastName = src.LastName
,tgt.EmailAddress = src.EmailAddress
,tgt.Status = 'U'
-- Physically delete target rows not in source
WHEN NOT MATCHED BY SOURCE
THEN DELETE
-- Stream output to outer query
OUTPUT
$ACTION
,src.SK
,src.FirstName
,src.LastName
,src.EmailAddress
)
AS changes
(
ACTION
,SK
,FirstName
,LastName
,EmailAddress
)
;
SELECT * FROM #source
SELECT * FROM #target
SELECT * FROM #debug
END
-- Load #1: All new rows
EXEC deleteme;
-- Load #2: No change (run the merge again)
-- There should be no change to target
-- Note there is no debug output
EXEC deleteme;
-- Load #3:
-- Record #1 unchanged
-- Record #2 changed (married, new email address)
-- Record #3 deleted
-- Record #4 added
UPDATE #source SET LastName='Smith',EmailAddress='mary.smith@blah.com' WHERE SK=2;
DELETE FROM #source WHERE SK=3;
INSERT INTO #source
(FirstName,LastName,EmailAddress)
VALUES
('Billy','Bob','william.robert@gmail.com')
EXEC deleteme;