DrColossos
Grünschnabel
Hi,
Ich habe folgendes Problem unter MSSQL (PGSQL & ORACLE kommen auch noch, hehe)
Hab eine Tabelle, zu der möchte ich über einen Trigger eine History-Tabelle füllen, die der aktuellen Tabelle identisch ist, allerdings noch eine ID-Spalte (muss sein wegen Primary Key), und noch eine Spalte, die angibt, ob der Datensatz eingefügt (aktion = 2), geändert (aktion = 3), oder gelöscht (aktion = 4) wurde.
Funktioniert bereits, bei INSERT, auch bei UPDATE und DELETE, bei beiden letzteren aber nur wenn HÖCHSTENS EIN Datensatz geändert gelöscht wird.
Problem ist, dass der Primärschlüsel, den ich für die History-Tabelle ermittle, mehrmals benutzt wird, das geht dann natürlich schief.
Ich müsste da eine Schleife einbauen, oder was auch immer ... wer kann mir helfen.
Kompletter Code ist angehängt,
Danke & Servus
GO
CREATE TABLE person
(
person_id int NOT NULL PRIMARY KEY,
person_name varchar(20),
person_alter int,
)
CREATE TABLE person_history
(
person_history_id int NOT NULL PRIMARY KEY,
aktion int NOT NULL,
person_id int NOT NULL,
person_name varchar(20),
person_alter int
)
GO
CREATE TRIGGER person_to_history
ON person
FOR UPDATE, DELETE
AS
DECLARE @action int
-- Aktion ermitteln
IF (SELECT MAX(person_id) FROM person WHERE person_id IN (SELECT person_id FROM deleted)) IS NULL
SELECT @action = 4
IF (SELECT MAX(person_id) FROM person_history WHERE person_id IN (SELECT person_id FROM deleted)) IS NULL
SELECT @action = 2
ELSE
SELECT @action = 3
-- Debugging ...
PRINT 'action: "' + CAST(@action AS varchar(20)) + '"'
DECLARE @cnt_npid int
SELECT @cnt_npid = (SELECT COUNT(person_id) FROM inserted)
PRINT 'COUNT neu PID: "' + CAST(@cnt_npid AS varchar(20)) + '"'
DECLARE @cnt_opid int
SELECT @cnt_opid = (SELECT COUNT(person_id) FROM deleted)
PRINT 'COUNT alte PID: "' + CAST(@cnt_opid AS varchar(20)) + '"'
DECLARE @npid int
SELECT @npid = (SELECT person_id FROM inserted)
PRINT 'neu PID: "' + CAST(@npid AS varchar(20)) + '"'
DECLARE @opid int
SELECT @opid = (SELECT person_id FROM deleted)
PRINT 'alte PID: "' + CAST(@opid AS varchar(20)) + '"'
DECLARE @max_person_history_id int
-- PK für historie-Tabelle ermitteln
SELECT @max_person_history_id = (SELECT MAX(person_history_id) FROM person_history)
IF @max_person_history_id IS NULL
SELECT @max_person_history_id = 1
ELSE
SELECT @max_person_history_id = @max_person_history_id + 1
PRINT '@max_person_history_id: "' + CAST(@max_person_history_id AS varchar(20)) + '"'
-- Datensatz einfügen
INSERT INTO person_history
SELECT @max_person_history_id, @action, * from DELETED
-- Testdaten
GO
INSERT INTO person values (1, 'A', 10)
INSERT INTO person values (2, 'B', 20)
INSERT INTO person values (3, 'C', 30)
-- Trigger-Test, funktioniert (genau ein Sat wird geändert)
UPDATE person SET person_name = 'Z' WHERE person_id = 1
-- Trigger-Test, scheitert, möchte mehrmal mit gleichem Primärschlüssel einfügen (mehrere Zeilen werden upgedated, hier drei)
UPDATE person SET person_name = 'Z'
Ich habe folgendes Problem unter MSSQL (PGSQL & ORACLE kommen auch noch, hehe)
Hab eine Tabelle, zu der möchte ich über einen Trigger eine History-Tabelle füllen, die der aktuellen Tabelle identisch ist, allerdings noch eine ID-Spalte (muss sein wegen Primary Key), und noch eine Spalte, die angibt, ob der Datensatz eingefügt (aktion = 2), geändert (aktion = 3), oder gelöscht (aktion = 4) wurde.
Funktioniert bereits, bei INSERT, auch bei UPDATE und DELETE, bei beiden letzteren aber nur wenn HÖCHSTENS EIN Datensatz geändert gelöscht wird.
Problem ist, dass der Primärschlüsel, den ich für die History-Tabelle ermittle, mehrmals benutzt wird, das geht dann natürlich schief.
Ich müsste da eine Schleife einbauen, oder was auch immer ... wer kann mir helfen.
Kompletter Code ist angehängt,
Danke & Servus
GO
CREATE TABLE person
(
person_id int NOT NULL PRIMARY KEY,
person_name varchar(20),
person_alter int,
)
CREATE TABLE person_history
(
person_history_id int NOT NULL PRIMARY KEY,
aktion int NOT NULL,
person_id int NOT NULL,
person_name varchar(20),
person_alter int
)
GO
CREATE TRIGGER person_to_history
ON person
FOR UPDATE, DELETE
AS
DECLARE @action int
-- Aktion ermitteln
IF (SELECT MAX(person_id) FROM person WHERE person_id IN (SELECT person_id FROM deleted)) IS NULL
SELECT @action = 4
IF (SELECT MAX(person_id) FROM person_history WHERE person_id IN (SELECT person_id FROM deleted)) IS NULL
SELECT @action = 2
ELSE
SELECT @action = 3
-- Debugging ...
PRINT 'action: "' + CAST(@action AS varchar(20)) + '"'
DECLARE @cnt_npid int
SELECT @cnt_npid = (SELECT COUNT(person_id) FROM inserted)
PRINT 'COUNT neu PID: "' + CAST(@cnt_npid AS varchar(20)) + '"'
DECLARE @cnt_opid int
SELECT @cnt_opid = (SELECT COUNT(person_id) FROM deleted)
PRINT 'COUNT alte PID: "' + CAST(@cnt_opid AS varchar(20)) + '"'
DECLARE @npid int
SELECT @npid = (SELECT person_id FROM inserted)
PRINT 'neu PID: "' + CAST(@npid AS varchar(20)) + '"'
DECLARE @opid int
SELECT @opid = (SELECT person_id FROM deleted)
PRINT 'alte PID: "' + CAST(@opid AS varchar(20)) + '"'
DECLARE @max_person_history_id int
-- PK für historie-Tabelle ermitteln
SELECT @max_person_history_id = (SELECT MAX(person_history_id) FROM person_history)
IF @max_person_history_id IS NULL
SELECT @max_person_history_id = 1
ELSE
SELECT @max_person_history_id = @max_person_history_id + 1
PRINT '@max_person_history_id: "' + CAST(@max_person_history_id AS varchar(20)) + '"'
-- Datensatz einfügen
INSERT INTO person_history
SELECT @max_person_history_id, @action, * from DELETED
-- Testdaten
GO
INSERT INTO person values (1, 'A', 10)
INSERT INTO person values (2, 'B', 20)
INSERT INTO person values (3, 'C', 30)
-- Trigger-Test, funktioniert (genau ein Sat wird geändert)
UPDATE person SET person_name = 'Z' WHERE person_id = 1
-- Trigger-Test, scheitert, möchte mehrmal mit gleichem Primärschlüssel einfügen (mehrere Zeilen werden upgedated, hier drei)
UPDATE person SET person_name = 'Z'