Quantcast
Channel: Für Entwickler: SQL Server Forum
Viewing all articles
Browse latest Browse all 1772

SCD 2 Merge und Auditing

$
0
0

Hallo,

ich habe folgendes Scenario implementiert:
- Staging (Tables) und Staging hub (Views)
- Core (Tables) und Core hub (Views)

Das Core besteht dabei aus Headtabelle (SCD 1 Verwaltung) und Versionstabelle (SCD 2 Verwaltung). Zur Datenintegration nutze ich MERGE-Statements und will deren Aktivität tracken (Audit). Für die Head-Tabelle habe ich das hinbekommen (1. Ergebnis im SSMS), für die Version-Tabelle leider nicht. Anbei der Code zum Ausführen:

--Staging tables
IF EXISTS (SELECT * FROM sys.objects WHERE name = (N'Stag_Kunde') AND type = 'u')
DROP TABLE dbo.Stag_Kunde;
GO

CREATE TABLE dbo.Stag_Kunde (
 kunde_bk nvarchar(10) not null default ''
,name nvarchar(50) null default ''
,vorname nvarchar(50) null default ''
,geburtsdatum date null default '1753-01-01'
,[status] nvarchar(20) null  default 'ledig'
,md_row_extract date not null default getdate()
,md_is_current smallint null default 1
,md_extracted_by nvarchar(50) default suser_sname()
);
GO

--Staging hub
IF EXISTS (SELECT * FROM sys.views WHERE name = (N'V_Stag_Kunde') AND type = 'V')
DROP VIEW dbo.V_Stag_Kunde;
GO

CREATE VIEW dbo.V_Stag_Kunde
AS
SELECT * FROM dbo.Stag_Kunde WHERE md_is_current = 1;
GO

IF EXISTS (SELECT * FROM sys.objects WHERE name = (N'Core_Kunde_H') AND type = 'u')
DROP TABLE dbo.Core_Kunde_H;
GO

--Core Head table
CREATE TABLE dbo.Core_Kunde_H (
 sid_h_kunde int identity(1,1) not null
,kunde_bk nvarchar(10) null
,md_inserted_on date not null default getdate()
,md_updated_on date null default getdate()
,md_is_current smallint default 1
,md_source nvarchar(10) default 'Staging'
,md_load_id nvarchar(5)
,md_action_by nvarchar(50) default suser_sname()
);
GO

IF EXISTS (SELECT * FROM sys.objects WHERE name = (N'Core_Kunde_V') AND type = 'u')
DROP TABLE dbo.Core_Kunde_V;
GO

--Core Version table
CREATE TABLE dbo.Core_Kunde_V (
 sid_v_kunde int identity(1,1) not null
,sid_h_kunde int not null
,name nvarchar(50) null
,vorname nvarchar(50) null
,geburtsdatum date null
,[status] nvarchar(50) null
,md_is_current smallint null default 1
,md_valid_from date not null default getdate()
,md_valid_until date null default '9999-12-31'
,md_source nvarchar(10) null default 'Staging'
,md_inserted_on date not null  default getdate()
,md_updated_on date null default getdate()
,md_load_id nvarchar(5) null
,md_action_by nvarchar(50) null default suser_sname()
);
GO

--Befüllen der Staging
DECLARE @date date
SET @date = GETDATE()-10

INSERT INTO dbo.Stag_Kunde
(kunde_bk, name, vorname, geburtsdatum, status, md_row_extract, md_is_current, md_extracted_by
)
VALUES ('100', 'Name1', 'Vorname1', '1972-03-24', 'ledig', @date, 1, SUSER_SNAME() ),
('101', 'Name1', 'Vorname2', '1943-04-02', 'verwitwet', @date, 1, SUSER_SNAME() ),
('102', 'Name2', 'Vorname3', '1963-08-25', 'verheiratet', @date, 1, SUSER_SNAME() )

--Befüllen des Cores (Dummy)
DECLARE @date1 date
SET @date1 = GETDATE()-10

INSERT INTO dbo.Core_Kunde_H
(kunde_bk, md_inserted_on, md_updated_on, md_source, md_load_id)
VALUES ('', @date1, @date1, 'Core', 0);
GO

DECLARE @date date
SET @date = GETDATE()-10

INSERT INTO dbo.Core_Kunde_V
(sid_h_kunde, name, vorname, geburtsdatum, status, md_valid_from, md_source, md_inserted_on, md_updated_on, md_load_id)
VALUES (1, 'keine Zuordnung', 'keine Zuordnung', '1753-01-01', 'keine Zuordnung', @date, 'Core', @date, @date, 0);
GO

/****************************************************************
**Merge Load
****************************************************************/
--Core Head
DECLARE @tabAction_Out Table (col1 nvarchar(20) )
DECLARE @intInsert_Count INT
,@intUpdate_Count INT
,@intDelete_Count INT
,@intLoad_ID INT
,@dateLoad_Date DATE

SET @intLoad_ID = 1
SET @dateLoad_Date = GETDATE()-4

MERGE INTO dbo.Core_Kunde_H AS t
USING (SELECT Kunde_bk FROM dbo.V_Stag_Kunde)
AS s (Kunde_bk)
ON (t.kunde_bk = s.kunde_bk)

WHEN MATCHED
THEN
UPDATE
SET md_updated_on = @dateLoad_Date

WHEN NOT MATCHED BY TARGET
THEN
INSERT (kunde_bk,md_inserted_on,md_updated_on,md_is_current,md_source,md_load_id,md_action_by)
VALUES (s.kunde_bk, @dateLoad_Date, @dateLoad_Date, 1, 'Staging', @intLoad_ID, suser_sname())

OUTPUT $Action as Merge_Action INTO @tabAction_Out;

SET @intInsert_Count = (SELECT COUNT(col1) FROM @tabAction_Out WHERE col1 = 'INSERT')
SET @intUpdate_Count = (SELECT COUNT(col1) FROM @tabAction_Out WHERE col1 = 'UPDATE')
SET @intDelete_Count = (SELECT COUNT(col1) FROM @tabAction_Out WHERE col1 = 'DELETE')

SELECT @intInsert_Count AS insert_count
     , @intUpdate_Count AS update_count
     , @intDelete_Count as delete_count

SELECT *
FROM dbo.Core_Kunde_H;
GO

--Core Version
DECLARE @intLoad_ID INT
,@dateLoad_Date DATE

SET @intLoad_ID = 1
SET @dateLoad_Date = GETDATE()-4

INSERT INTO dbo.Core_Kunde_V (
 sid_h_kunde
,name
,vorname
,geburtsdatum
,status
,md_is_current
,md_valid_from
,md_valid_until
,md_source
,md_inserted_on
,md_updated_on
,md_load_id
,md_action_by
)
SELECT
 sid_h_kunde
,name
,vorname
,geburtsdatum
,status
,md_is_current
,md_valid_from
,md_valid_until
,md_source
,md_inserted_on
,md_updated_on
,md_load_id
,md_action_by
FROM (
MERGE INTO dbo.Core_Kunde_V AS t
USING (
SELECT ISNULL(t2.sid_h_kunde, 1) AS sid_h_kunde, t1.Kunde_bk, name, vorname, geburtsdatum, status
FROM dbo.V_Stag_Kunde AS t1
LEFT JOIN (SELECT sid_h_kunde, kunde_bk FROM dbo.Core_Kunde_H) AS t2
     ON t2.kunde_bk = t1.Kunde_bk
) AS s
(sid_h_kunde, Kunde_bk, name, vorname, geburtsdatum, status)
ON (t.sid_h_kunde = s.sid_h_kunde)

WHEN MATCHED
AND t.md_is_current = 1
AND (
t.name != s.name
OR t.vorname != s.vorname
OR t.geburtsdatum != s.geburtsdatum
OR t.status != s.status )
THEN
UPDATE SET
 t.md_is_current = 0
,t.md_updated_on = getdate()
,t.md_action_by = suser_sname()

WHEN NOT MATCHED BY TARGET
THEN
INSERT (sid_h_kunde, name, vorname, geburtsdatum, status, md_is_current, md_valid_from, md_valid_until, md_source, md_inserted_on, md_updated_on, md_load_id)
VALUES (s.sid_h_kunde, s.name, s.vorname, s.geburtsdatum, s.status, 1, @dateLoad_Date, '9999-12-31', 'Staging', @dateLoad_Date, @dateLoad_Date, @intLoad_ID)

OUTPUT $Action as Merge_Action
,s.sid_h_kunde
,s.Kunde_bk
,s.name
,s.vorname
,s.geburtsdatum
,s.status
,1 as md_is_current
,getdate() as md_valid_from
, '9999-12-31' as md_valid_until
,'Staging' as md_source
,getdate() as md_inserted_on
,getdate() as md_updated_on
,@intLoad_ID as md_load_id
,suser_sname() as md_action_by
) AS Merge_Output
WHERE Merge_Output.Merge_Action = 'UPDATE';
;

SELECT *
FROM dbo.Core_Kunde_V;
GO

Ich möchte das Audit des SCD2-Merge für die Versionstabelle so dargestellt bekommen wie bei der Headtabelle (1. Ergebnis des o.g. SQL's).

Any ideas (feel free to change the sql statement)?

Danke, :)




Viewing all articles
Browse latest Browse all 1772

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>