Hallo,
zum Thema "Protokollierung von Änderungen an Datensätzen" gibt es ja schon diverse Threads.
Ich möchte trotzdem neu aufmachen, meinen Lösungsansatz zu Dikussion stellen und -wenn möglich- um einen Stupps in die richtige Richtung bitten.
Angeregt durch einen ähnlichen Thread aus diesem Forum habe diesen Plan:
[highlight=sql]
-- Änderungsprotokolldatei (Prinzipskizze, eine Datei für die Änderung aller Tabellen)
CREATE TABLE Protokoll
(
Tabelle sysname,
PK Int,
Nutzer varchar(30),
Datum smalldatetime,
Alt xml,
Neu xml
)
GO
-- Trigger der verschiedenen Tabellen (Dtrig entsprechend mit deleted)
CREATE TRIGGER T_IU_Kunde ON Kunde
FOR INSERT,Update
AS
INSERT INTO Protokoll(Tabelle,PK,Nutzer,Datum,Alt, Neu)
SELECT 'Kunde',KundeID, SYSTEM_USER, GETDATE(),
(SELECT Kunde.* FROM Kunde WHERE KundeID=imain.KundeID FOR XML AUTO),
(SELECT inserted.* FROM inserted WHERE inserted.KundeID = imain.kundeID FOR XML AUTO)
FROM inserted imain
GO
[/highlight]
Was mit an dieser Lösung gefällt:
- egal wie sich die Tabellenstruktur ändert, ich muss das nie mehr anfassen bzw. bedenken
- ich kann das 1:1 in alle Tabellen übernehmen und muss nur die Primärschlüssel ändern, schon sollte es gehen
- alle Änderungen stehen in einer zentralen Datei
Was mir nicht gefällt:
- Mit jeder klitzekleinen Änderung wird der gesamte Datensatz kopiert, mein Datenbestand wird sehr schnell anwachsen
Was mit unklar ist:
- Wie sieht das längerfristig mit der Performance aus?
Ich suche nun nach einer Lösung, die mir wenigstens die beiden xml - Daten alt / neu in der Form bearbeitet, dass ich nur noch die tatsächlichen Änderungen zurückbekomme. Also etwas in der Form "XMLDiff(alt,neu) Returns XML". Ich hoffe, dass das eine deutliche Platzersparnis bringt.
Ziel sollte etwas in der Art sein:
[highlight=sql]
CREATE TABLE Protokoll
(
...
Diff xml
)
GO
-- Trigger der verschiedenen Tabellen (Dtrig entsprechend mit deleted)
CREATE TRIGGER ...
INSERT INTO Protokoll(Tabelle,PK,Nutzer,Datum,Diff)
SELECT 'Kunde',KundeID, SYSTEM_USER, GETDATE(),
XMLDiff(
(SELECT Kunde.* FROM Kunde WHERE KundeID=imain.KundeID FOR XML AUTO),
(SELECT inserted.* FROM inserted WHERE inserted.KundeID = imain.kundeID FOR XML AUTO)
)
FROM inserted imain
GO
[/highlight]
Vielleicht kann mir jemand zu "XMLDiff()" einen Tipp geben.
Ich habe schon mit xml.nodes() und .values() herumprobiert, aber komme leider nicht so richtig 'rein so dass ich besser hier auch meine verwirrtten Versuche noch nicht poste.
Ich möchte auch keine fertige Lösung aber vielleicht einen Tipp, wie man sowas angeht da ich mit XML noch sehr wenig Erfahrungen habe.
Interessant wäre außerdem ein Ansatz, wie man die so bearbeiteten XML - Daten dann für ein Änderungsprotokoll wieder gegenüber dem Nutzer aufbereitet, so in der Art
01.02.2011 sa Name2: "Meier" -> "Schulze"; Ort: "Bonn" -> "New York"
...
Edit: MS SQL 2005 und 2008R2
Danke im Vorauss
Tino
P.S. Das Ganze ist ein Nebenschauplatz eines größeren Projektes mit Termindruck, bitte entschuldigt, wenn ich nicht sofort auf Antworten reagieren sollte.
zum Thema "Protokollierung von Änderungen an Datensätzen" gibt es ja schon diverse Threads.
Ich möchte trotzdem neu aufmachen, meinen Lösungsansatz zu Dikussion stellen und -wenn möglich- um einen Stupps in die richtige Richtung bitten.
Angeregt durch einen ähnlichen Thread aus diesem Forum habe diesen Plan:
[highlight=sql]
-- Änderungsprotokolldatei (Prinzipskizze, eine Datei für die Änderung aller Tabellen)
CREATE TABLE Protokoll
(
Tabelle sysname,
PK Int,
Nutzer varchar(30),
Datum smalldatetime,
Alt xml,
Neu xml
)
GO
-- Trigger der verschiedenen Tabellen (Dtrig entsprechend mit deleted)
CREATE TRIGGER T_IU_Kunde ON Kunde
FOR INSERT,Update
AS
INSERT INTO Protokoll(Tabelle,PK,Nutzer,Datum,Alt, Neu)
SELECT 'Kunde',KundeID, SYSTEM_USER, GETDATE(),
(SELECT Kunde.* FROM Kunde WHERE KundeID=imain.KundeID FOR XML AUTO),
(SELECT inserted.* FROM inserted WHERE inserted.KundeID = imain.kundeID FOR XML AUTO)
FROM inserted imain
GO
[/highlight]
Was mit an dieser Lösung gefällt:
- egal wie sich die Tabellenstruktur ändert, ich muss das nie mehr anfassen bzw. bedenken
- ich kann das 1:1 in alle Tabellen übernehmen und muss nur die Primärschlüssel ändern, schon sollte es gehen
- alle Änderungen stehen in einer zentralen Datei
Was mir nicht gefällt:
- Mit jeder klitzekleinen Änderung wird der gesamte Datensatz kopiert, mein Datenbestand wird sehr schnell anwachsen
Was mit unklar ist:
- Wie sieht das längerfristig mit der Performance aus?
Ich suche nun nach einer Lösung, die mir wenigstens die beiden xml - Daten alt / neu in der Form bearbeitet, dass ich nur noch die tatsächlichen Änderungen zurückbekomme. Also etwas in der Form "XMLDiff(alt,neu) Returns XML". Ich hoffe, dass das eine deutliche Platzersparnis bringt.
Ziel sollte etwas in der Art sein:
[highlight=sql]
CREATE TABLE Protokoll
(
...
Diff xml
)
GO
-- Trigger der verschiedenen Tabellen (Dtrig entsprechend mit deleted)
CREATE TRIGGER ...
INSERT INTO Protokoll(Tabelle,PK,Nutzer,Datum,Diff)
SELECT 'Kunde',KundeID, SYSTEM_USER, GETDATE(),
XMLDiff(
(SELECT Kunde.* FROM Kunde WHERE KundeID=imain.KundeID FOR XML AUTO),
(SELECT inserted.* FROM inserted WHERE inserted.KundeID = imain.kundeID FOR XML AUTO)
)
FROM inserted imain
GO
[/highlight]
Vielleicht kann mir jemand zu "XMLDiff()" einen Tipp geben.
Ich habe schon mit xml.nodes() und .values() herumprobiert, aber komme leider nicht so richtig 'rein so dass ich besser hier auch meine verwirrtten Versuche noch nicht poste.
Ich möchte auch keine fertige Lösung aber vielleicht einen Tipp, wie man sowas angeht da ich mit XML noch sehr wenig Erfahrungen habe.
Interessant wäre außerdem ein Ansatz, wie man die so bearbeiteten XML - Daten dann für ein Änderungsprotokoll wieder gegenüber dem Nutzer aufbereitet, so in der Art
01.02.2011 sa Name2: "Meier" -> "Schulze"; Ort: "Bonn" -> "New York"
...
Edit: MS SQL 2005 und 2008R2
Danke im Vorauss
Tino
P.S. Das Ganze ist ein Nebenschauplatz eines größeren Projektes mit Termindruck, bitte entschuldigt, wenn ich nicht sofort auf Antworten reagieren sollte.
Comment