Einzelnen Beitrag anzeigen

mace

Registriert seit: 13. Jan 2006
27 Beiträge
 
Delphi 7 Personal
 
#1

Protokoll Trigger mit > 1 Datensätze

  Alt 12. Feb 2007, 12:55
Datenbank: MS SQL • Version: 2000 • Zugriff über: ADO Komponenten
Hallo zusammen!

Die Trigger machen mich kaputt.
Meine Aufgabe ist es, dafür zu sorgen, dass solch einer die Änderungen relevanter Felder einer Tabelle dokumentiert und in einer Protokolltab speichert.
Erst hatte ich damit angefangen, ihn so zu erstellen, das variabel die Felder erkennt + eingetragen werden. sah in etwa so aus, musste aber doch deutlich abgeändert werden
Damit konnt ich die Anforderungen dann aber schlussendlich nicht erfüllen und somit bin ich auf die konservative(?!) Methode umgestiegen und melde Feld für Feld an und dokumentiere es, wenn Änderungen vorhanden sind.

Sieht dann in etwa wie folgt aus:
(hab mal alle Stellen reinkopiert, ab dem rot gekennzeichneten wirds interessant)

SQL-Code:
ALTER TRIGGER [TR_Logxxx] ON [dbo].[xxx]
FOR INSERT, UPDATE, DELETE
AS

-- Felderdeklaration der Protokolltabelle für Insert, ausgenommen alter/neuer Wert
Declare @Username nvarchar(40)
Declare @UpdateDate datetime
Declare @TableName nvarchar(255)
Declare @Fieldname nvarchar(150)
.
.
.

-- statische Werte der Protokolltabellenfelder
Select @UserName = system_user
Select @UpdateDate = convert(varchar(8), getdate(), 112) + ' ' + convert(varchar(12), getdate(), 114)
.
.
.



-- Aktion bestimmen

if exists (select * from inserted)
begin
   if exists (select * from deleted)
   begin
      select @Aktion = 'Datensatz geändert'
      select @PersNr = deleted.PersID from deleted
      Select @ObjSchluessel = deleted.ID from deleted
      
      print @deleted
      print @Aktion

   end
   else
   begin
      select @Aktion = 'Datensatz eingefügt'
      Select @PersNr = inserted.PersID from inserted
      Select @ObjSchluessel = inserted.ID from inserted
   end
end
else
begin
   select @Aktion = 'Datensatz gelöscht.'
   select @PersNr = deleted.PersID from deleted
   select @ObjSchluessel = deleted.ID from deleted
end

select @deleted = inserted.geloescht from inserted
if (@deleted=1)
begin
   select @Aktion = 'Datensatz gelöscht'
end
ab hier wirds interessant
SQL-Code:
-- Deklaration der Felder
Declare @OldIDSeminar nvarchar(255)
Declare @OldAnmeldedatum nvarchar(255)
Declare @OldUnterlagenerledigt nvarchar(255)
Declare @OldTeilnehmerbestaetigung nvarchar(255)
Declare @OldBewirtschaftet nvarchar(255)
...
Declare @NewIDSeminar nvarchar(255)
Declare @NewAnmeldedatum nvarchar(255)
Declare @NewUnterlagenerledigt nvarchar(255)
Declare @NewTeilnehmerbestaetigung nvarchar(255)
Declare @NewBewirtschaftet nvarchar(255)
...

-- Zuweisen der alten Feldinhalte
Select @OldIDSeminar = deleted.IDSeminar from deleted
Select @OldAnmeldedatum = convert(nvarchar, deleted.Anmeldedatum, 104) from deleted
Select @OldUnterlagenerledigt = convert(nvarchar, deleted.Unterlagenerledigt, 104) from deleted
Select @OldTeilnehmerbestaetigung = convert(nvarchar, deleted.Teilnehmerbestaetigung, 104) from deleted
Select @OldBewirtschaftet = deleted.Bewirtschaftet from deleted
...

-- Zuweisen der neuen Feldinhalte
Select @NewIDSeminar = inserted.IDSeminar from inserted
Select @NewAnmeldedatum = convert(nvarchar, inserted.Anmeldedatum, 104) from inserted
Select @NewUnterlagenerledigt = convert(nvarchar, inserted.Unterlagenerledigt, 104) from inserted
Select @NewTeilnehmerbestaetigung = convert(nvarchar, inserted.Teilnehmerbestaetigung, 104) from inserted
Select @NewBewirtschaftet = inserted.Bewirtschaftet from inserted
...

IF (@OldAnmeldedatum <> @NewAnmeldedatum ) OR (@OldAnmeldedatum is null and not @NewAnmeldedatum is null) OR (not @OldAnmeldedatum is null and @NewAnmeldedatum is null)
   OR (not @OldIDSeminar is null and @deleted = 1)
begin
   Insert into tabProtokoll (Username, Logdate, OldValue, NewValue, TableName, FieldName, PersNr, ObjektSchluessel, Aktion, Maskenname)
   Values (Current_User, @UpdateDate, @OldAnmeldedatum , @NewAnmeldedatum , @TableName, 'Anmeldedatum', @PersNr, @ObjSchluessel, @Aktion, @Maskenname)
end

Einfach als Beispiel das Anmeldedatum genommen, dass wird dann für alle Felder gemacht.
Mein Problem ist dabei das Aktualisieren/Löschen mehrerer Datensätze.
Solang ich einen Datensatz inserten, updaten, deleten möchte alles einwandfrei.

Sobald es mehrere sind kommt:

Server: Nachr.-Nr. 512, Schweregrad 16, Status 1, Prozedur TR_Logxxx, Zeile 212
Die Unterabfrage gab mehr als einen Wert zurück. Das ist ungültig, wenn die Unterabfrage auf =, !=, <, <= , >, >= folgt oder als Ausdruck verwendet wird.
Die Anweisung wurde beendet.

Die Frage also, was macht er da, warum entsteht der Fehler und wie ist er zu beseitigen?

Viel Text, hoffentlich viel Hilfe, ich sag schonmal viel Danke!

Grüße,
mace

//Edit: Threadname geändert, um Missverständnisse zu vermeiden..
Conscience is what hurts when everything else feels so good.
  Mit Zitat antworten Zitat