MS SQL Datenbanktrigger - Problem
Hallo zusammen,
bin neu hier und hab gleich mal ne Frage oder besser gesagt ein Problem!
Wäre super wenn mir jemand helfen könnte...
Ich habe einen Datenbanktrigger für eine Tabelle auf einem MS SQL Server geschrieben. Dieser Trigger soll bei einem Insert Befehl auf eine bestimmt Tabelle ein Feld in einer anderen Tabelle mit einem Wert aktualisieren.
Hier mal mein Code:
CREATE TRIGGER trigg_kontID_anlegen
ON <Datenbank>
FOR INSERT
AS
DECLARE @highestid int
DECLARE @accidinserted VARCHAR(255)
DECLARE @idnew int
SELECT @highestid = (SELECT MAX(New_contactid) FROM ContactExtensionBase)
PRINT @highestid
SELECT @accidinserted = (SELECT ContactId FROM Inserted)
PRINT @accidinserted
SELECT @accidinserted = '{'+@accIdInserted +'}'
PRINT @accidinserted
SELECT @idnew = @highestid +1
PRINT @idnew
Update ContactExtensionBase SET New_contactid = @idnew WHERE ContactId = (@accIdInserted)
Habe über den QueryAnalyzer die Werte geprüft...das lesen des höchsten Wertes klappt, das ermitteln der AccountId und schreiben in die entsprechende Variable klappt etc....aber er schreibt den Wert nicht in die Tabelle! Ersetze ich aber in der WHERE Klausel die Variable durch einen fixen Wert in der Form wie er auch in der DB vorkommt dann klappt es. Was ebenfalls funktioniert ist, wenn ich der in der Where Klausel verwendeten Variable vorher einen festen Wert zuweise.
hat jemand ne Idee woran das liegen könnte? Wäre super weiß langsam net mehr weiter...
Hoffe ist einigermaßen verständlich geschildert das Problem
schon mal danke im Voraus
freshToto
bin neu hier und hab gleich mal ne Frage oder besser gesagt ein Problem!
Wäre super wenn mir jemand helfen könnte...
Ich habe einen Datenbanktrigger für eine Tabelle auf einem MS SQL Server geschrieben. Dieser Trigger soll bei einem Insert Befehl auf eine bestimmt Tabelle ein Feld in einer anderen Tabelle mit einem Wert aktualisieren.
Hier mal mein Code:
CREATE TRIGGER trigg_kontID_anlegen
ON <Datenbank>
FOR INSERT
AS
DECLARE @highestid int
DECLARE @accidinserted VARCHAR(255)
DECLARE @idnew int
SELECT @highestid = (SELECT MAX(New_contactid) FROM ContactExtensionBase)
PRINT @highestid
SELECT @accidinserted = (SELECT ContactId FROM Inserted)
PRINT @accidinserted
SELECT @accidinserted = '{'+@accIdInserted +'}'
PRINT @accidinserted
SELECT @idnew = @highestid +1
PRINT @idnew
Update ContactExtensionBase SET New_contactid = @idnew WHERE ContactId = (@accIdInserted)
Habe über den QueryAnalyzer die Werte geprüft...das lesen des höchsten Wertes klappt, das ermitteln der AccountId und schreiben in die entsprechende Variable klappt etc....aber er schreibt den Wert nicht in die Tabelle! Ersetze ich aber in der WHERE Klausel die Variable durch einen fixen Wert in der Form wie er auch in der DB vorkommt dann klappt es. Was ebenfalls funktioniert ist, wenn ich der in der Where Klausel verwendeten Variable vorher einen festen Wert zuweise.
hat jemand ne Idee woran das liegen könnte? Wäre super weiß langsam net mehr weiter...
Hoffe ist einigermaßen verständlich geschildert das Problem
schon mal danke im Voraus
freshToto
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 137321
Url: https://administrator.de/forum/ms-sql-datenbanktrigger-problem-137321.html
Ausgedruckt am: 11.04.2025 um 00:04 Uhr
16 Kommentare
Neuester Kommentar
Moin.
SELECT @accidinserted = '{'+@accIdInserted +'}'
accidInserted ist doch sicher ein int??? Das müsste schon knallen. Oder benutzt Du Text-IDs?
Versuch doch mal:
Update ContactExtensionBase SET New_contactid = @idnew WHERE ContactId = (SELECT ContactId FROM Inserted)
bzw.
Update ContactExtensionBase SET New_contactid = @idnew WHERE ContactId = '{' + cast((SELECT ContactId FROM Inserted) as varchar) + '}'
bzw.
Update ContactExtensionBase SET New_contactid = @idnew WHERE ContactId = '{' + (SELECT ContactId FROM Inserted) + '}'
HTH
MK
SELECT @accidinserted = '{'+@accIdInserted +'}'
accidInserted ist doch sicher ein int??? Das müsste schon knallen. Oder benutzt Du Text-IDs?
Versuch doch mal:
Update ContactExtensionBase SET New_contactid = @idnew WHERE ContactId = (SELECT ContactId FROM Inserted)
bzw.
Update ContactExtensionBase SET New_contactid = @idnew WHERE ContactId = '{' + cast((SELECT ContactId FROM Inserted) as varchar) + '}'
bzw.
Update ContactExtensionBase SET New_contactid = @idnew WHERE ContactId = '{' + (SELECT ContactId FROM Inserted) + '}'
HTH
MK
Moin freshToto,
was mir spontan auffällt:
hat die ContactId in der Tabelle geschweifte Klammern oder nicht?
...
Im ersten Teil ist die ContactId anscheinend ohne geschweifte Klammern drumrum, deshalb setzt Du sie. Im zweiten Teil fragst Du aber die ContactId ab mit dem Wert, dem Du vorher die Klammern verpaßt hast. Wenn beide Anweisungen sich auf die selbe Tabelle beziehen, dann kann das kaum klappen. Wenn sie sich auf verschiedene Tabellen beziehen, dann müßte diese ContactId einmal mit und einmal ohne die Klammern gespeichert sein.
Sollte das Dein Problem nicht lösen, wäre Deine Tabellendefinition und auch ein, zwei Beispieldatensätze hilfreich, um Dir weiterzuhelfen.
Achja, noch ein kleiner Nachtrag: Dein Trigger wird auch nur richtig funktionieren, wenn Du nur einen DS aktualisierst. Bei mehreren bräuchtest Du einen Cursor über inserted oder schreibst die Befehle so um, daß in einem Rutsch alle DS aktualisiert werden.
Gruß, Mad Max
was mir spontan auffällt:
hat die ContactId in der Tabelle geschweifte Klammern oder nicht?
SELECT @accIdInserted = (SELECT ContactId FROM Inserted)
PRINT @accIdInserted
SELECT @accIdInserted = '{'+@accIdInserted +'}'
... WHERE ContactId = (@accIdInserted)
Im ersten Teil ist die ContactId anscheinend ohne geschweifte Klammern drumrum, deshalb setzt Du sie. Im zweiten Teil fragst Du aber die ContactId ab mit dem Wert, dem Du vorher die Klammern verpaßt hast. Wenn beide Anweisungen sich auf die selbe Tabelle beziehen, dann kann das kaum klappen. Wenn sie sich auf verschiedene Tabellen beziehen, dann müßte diese ContactId einmal mit und einmal ohne die Klammern gespeichert sein.
Sollte das Dein Problem nicht lösen, wäre Deine Tabellendefinition und auch ein, zwei Beispieldatensätze hilfreich, um Dir weiterzuhelfen.
Achja, noch ein kleiner Nachtrag: Dein Trigger wird auch nur richtig funktionieren, wenn Du nur einen DS aktualisierst. Bei mehreren bräuchtest Du einen Cursor über inserted oder schreibst die Befehle so um, daß in einem Rutsch alle DS aktualisiert werden.
Gruß, Mad Max
Moin.
Kann es sein, dass der Trigger versucht zu updaten (extensionbase), während Du noch einfügst?
Poste mal die Tabellen struktur und den Insert in die beiden Tabellen. Irgendetwas stimmt da nicht.
Ich arbeite hier mit zig Update und Insert Triggern. Und eigentlich ist das überhaupt kein Problem.
HTH
MK
ja der eintrag den ich updaten will existiert bereits!
das ganze läuft so ab:
ich füge über die oberfläche des programms einen datensatz hinzu
der datensatz wird in der contactbase angelegt und ebenfalls ein verknüpfter Datensatz in der extensionbase
hier sind aber bis auf die ContactId alle felder <NULL> und eins dieser felder möchte ich mit dem Update befehl befüllen...
das ganze läuft so ab:
ich füge über die oberfläche des programms einen datensatz hinzu
der datensatz wird in der contactbase angelegt und ebenfalls ein verknüpfter Datensatz in der extensionbase
hier sind aber bis auf die ContactId alle felder <NULL> und eins dieser felder möchte ich mit dem Update befehl befüllen...
Kann es sein, dass der Trigger versucht zu updaten (extensionbase), während Du noch einfügst?
Poste mal die Tabellen struktur und den Insert in die beiden Tabellen. Irgendetwas stimmt da nicht.
Ich arbeite hier mit zig Update und Insert Triggern. Und eigentlich ist das überhaupt kein Problem.
HTH
MK
Hallo freshToto,
nach Deinen Infos habe ich jetzt mal Deine Sachen nachgebildet:
Einzige Änderung, die ich gemacht habe, ist, daß ich ein IsNull beim Lesen der New_contactid dazugefügt habe, damit auch beim ersten Eintrag was ordentliches zurückkommt.
Also bei mir läuft das.
Also gibt es folgende Möglichkeiten:
1. Wie es thaenhusen schon angesprochen hat, ContactExtensionBase wird erst nach ContactBase geschrieben, der DS existiert also zur Laufzeit des Triggers noch nicht.
2. Ich hab das auf einer DB mit ohne SP ausprobiert, vielleicht macht irgendein SP etwas, was Probleme bereitet.
Aber ich tendiere eher zu Möglichkeit 1.
Gruß, Mad Max
nach Deinen Infos habe ich jetzt mal Deine Sachen nachgebildet:
create table ContactBase (ContactId uniqueidentifier, StateCode int, DeletionStateCode int, FirstName varchar (50), LastName varchar (50))
go
create table ContactExtensionBase (ContactId uniqueidentifier, New_contactid int)
go
CREATE TRIGGER trigg_kontID_anlegen
ON ContactBase
FOR INSERT
AS
DECLARE @highestId int
DECLARE @accIdInserted VARCHAR(255)
DECLARE @idNew int
SELECT @highestId = (SELECT IsNull (MAX(New_contactid), 0) FROM ContactExtensionBase)
PRINT @highestId
SELECT @accIdInserted = (SELECT ContactId FROM Inserted)
PRINT @accIdInserted
SELECT @accIdInserted = '{'+@accIdInserted +'}'
PRINT @accIdInserted
SELECT @idNew = @highestId +1
PRINT @idNew
Update ContactExtensionBase SET New_contactid = @idNew WHERE ContactId = (@accIdInserted)
go
INSERT INTO ContactExtensionBase (ContactId)
VALUES('{32E5C0B2-1F68-DB11-807E-005056C00001}')
INSERT INTO ContactBase (ContactId, StateCode, DeletionStateCode, FirstName, LastName)
VALUES('{32E5C0B2-1F68-DB11-807E-005056C00001}', 0, 0, 'Name', 'Lname')
INSERT INTO ContactExtensionBase (ContactId)
VALUES('{32E5C0B2-1F68-DB11-807E-005056C00002}')
INSERT INTO ContactBase (ContactId, StateCode, DeletionStateCode, FirstName, LastName)
VALUES('{32E5C0B2-1F68-DB11-807E-005056C00002}', 0, 0, 'Name', 'Lname')
select * from ContactBase
select * from ContactExtensionBase
go
Also bei mir läuft das.
Also gibt es folgende Möglichkeiten:
1. Wie es thaenhusen schon angesprochen hat, ContactExtensionBase wird erst nach ContactBase geschrieben, der DS existiert also zur Laufzeit des Triggers noch nicht.
2. Ich hab das auf einer DB mit ohne SP ausprobiert, vielleicht macht irgendein SP etwas, was Probleme bereitet.
Aber ich tendiere eher zu Möglichkeit 1.
Gruß, Mad Max
Nabend freshToto,
zeitverzögert bringt ja nix, die Datensätze werden ja nicht parallel angelegt. Mit einer Warteschleife im Trigger würdest Du bis zum Sankt-Nimmerleinstag warten.
Wie prüft man das? Das Update ohne Ergebnis ist ja gewissermaßen die Prüfung. Du könntest am Anfang vom Trigger ein select machen, aber der Vergleich wäre ja derselbe wie imUpdate auch. Ich würde wohl im Profiler die Reihenfolge prüfen. Wenn Du den hast
Aber schreib Deinen Trigger doch einfach nicht für ContactBase, sondern für ContactExtensionBase. Ist ja sowieso sinnvoller, denn eigentlich willst Du ja nur dem neuen Datensatz eine Nummer verpassen, der Bezug zu ContactBase interessiert in dem Moment doch gar nicht.
Gruß, Mad Max
zeitverzögert bringt ja nix, die Datensätze werden ja nicht parallel angelegt. Mit einer Warteschleife im Trigger würdest Du bis zum Sankt-Nimmerleinstag warten.
Wie prüft man das? Das Update ohne Ergebnis ist ja gewissermaßen die Prüfung. Du könntest am Anfang vom Trigger ein select machen, aber der Vergleich wäre ja derselbe wie imUpdate auch. Ich würde wohl im Profiler die Reihenfolge prüfen. Wenn Du den hast
Aber schreib Deinen Trigger doch einfach nicht für ContactBase, sondern für ContactExtensionBase. Ist ja sowieso sinnvoller, denn eigentlich willst Du ja nur dem neuen Datensatz eine Nummer verpassen, der Bezug zu ContactBase interessiert in dem Moment doch gar nicht.
Gruß, Mad Max