freshtoto
Goto Top

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

Content-Key: 137321

Url: https://administrator.de/contentid/137321

Printed on: April 24, 2024 at 10:04 o'clock

Member: thaenhusen
thaenhusen Mar 03, 2010 at 14:24:08 (UTC)
Goto Top
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
Member: freshToto
freshToto Mar 04, 2010 at 07:15:12 (UTC)
Goto Top
servus,
erstmal danke für deine schnelle antwort und die vorschläge!
werde das gleich mal ausprobieren...

die @accidinserted ist kein Int...die Variable habe ich als Varchar und die werte aus der Tabelle die da rein sollen haben diese Form: {'DC4FE843-A41F-DF11-92A7-005056C00008'} ist der primärschlüssel der tabelle
und hat den typ uniqueidentifier...habe auch schon probiert die variable wo dieser wert rein soll als uniqueidentifier zu deklarieren aber auch ohne erfolg...
Member: MadMax
MadMax Mar 04, 2010 at 08:05:00 (UTC)
Goto Top
Moin freshToto,

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
Member: freshToto
freshToto Mar 04, 2010 at 08:23:03 (UTC)
Goto Top
hallo Mad Max,
erstmal danke!
wenn ich mir den Tabelleninhalt im SQL Manager anzeigen lasse sind die { }-Klammern zu sehen...wenn ich den inhalt mit dem query analyzer auslese sind sie aber nicht dabei...habe deshalb schon probiert die klammern der variablen mit zu geben wie in dem beispiel das ich gepostet hab...hab es aber auch schon ohne versucht!
werde gleich noch genauere Infos zu den Tabellen inkl. Datensätze posten.
das es keine ideallösung ist mit dem trigger weiß ich...aber wird eher unwahrscheinlich sein das mehrere DS zeitgleich aktualisiert werden und brauche diese where funktion auch in einem anderen zusammenhang
wie meinst du das mit dem cursor? muss da ein cursor auf den angelegten DS gelesetzt werden oder wie funktioniert das?

gruß
freshToto
Member: MadMax
MadMax Mar 04, 2010 at 12:06:39 (UTC)
Goto Top
Moin freshToto,

geh mal davon aus, daß da keine geschweiften Klammern drumrum sind.

Mit dem Cursor meine ich, daß Du alle DS in inserted einzeln abläufst und verarbeitest.

Gruß, Mad Max
Member: freshToto
freshToto Mar 04, 2010 at 12:16:38 (UTC)
Goto Top
servus,
ok werde mir das bei gelegenheit mal anschauen!
kann derzeit leider nicht an die umgebung dran...handelt sich um ne virtuelle testumgebung die gerade umgezogen wird (chaotische geschichte) face-smile

werde eure vorschläge ausprobieren bzw. umsetzen sobald ich wieder meine VM zur Verfügung habe...werde mich dann wieder an auch richten!
auf jeden fall schon mal danke für die tipps!

gruß
freshToto
Member: freshToto
freshToto Mar 19, 2010 at 11:08:49 (UTC)
Goto Top
hallo,
konnte leider länger nicht an dem problem arbeiten habe erst heute wieder damit angefangen!

@thaenhusen:
habe deine code vorschläge ausprobiert jedoch ohne erfolg!
bei dem letzten beispiel bekomme ich zudem einen syntaxfehler (ungültiger Operator für Datentyp. Operator ist add, Typ ist uniqueidentifier.)

hier nocheinmal ein paar infos zu meinen tabellen:

tabelle 1: contactbase

ContactId uniqueidentifier (vom System vorgegeben)
Name

tabelle 2: contactextensionbase

ContactId uniqueidentifier (vom System vorgegeben)
New_contactid int (hier soll die hochgezählte ID reingeschrieben werden)

habt ihr noch ne idee wo mein problem liegen könnte? bekomme langsam etwas druck und hab keine idee mehr...
gibt es vielleicht ne möglichkeit ohne trigger einen wert bei einem insert befehl in eine andere tabelle zu schreiben??

bin für jeden tip dankbar!

gruß
freshToto
Member: thaenhusen
thaenhusen Mar 19, 2010 at 12:19:49 (UTC)
Goto Top
Moin.

Hatte ich nicht darauf geachtet:

Hast Du denn in der ContactExtensionBase schon einen Eintrag der Update-bar ist?
Ansonsten musst Du das als Insert formulieren.

HTH
MK
Member: freshToto
freshToto Mar 19, 2010 at 12:58:30 (UTC)
Goto Top
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...
Member: thaenhusen
thaenhusen Mar 19, 2010 at 15:04:07 (UTC)
Goto Top
Moin.

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...

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
Member: freshToto
freshToto Mar 19, 2010 at 15:28:49 (UTC)
Goto Top
Nein ich denke nicht. Ich habe den Trigger nämlich schon mit fixen Werten getestet. Das heißt ich habe in das Update Statement statt der Variable im WHERE Teil einen fixen Wert eingetragen (z.B. WHERE ContactId = {32E5C0B2-1F68-DB11-807E-005056C00001}) und das hat dann funktioniert!
also gehe ich mal von aus das er fertig ist!?

was möchtest du bei der db struktur genau haben? ist kein selbstentwickeltes produkt! es geht hier um microsofts crm ich habe hier nur über das crm die db angepasst und möchte dieses feld jetzt mit einem trigger befüllen!

zum testen des triggers im sql query analyzer nutze ich folgenden insert
USE *_MSCRM

GO

SET NOCOUNT ON

INSERT INTO ContactBase (ContactId, StateCode, DeletionStateCode, FirstName, LastName)
VALUES('{32E5C0B2-1F68-DB11-807E-005056C00001}', 0, 0, 'Name', 'Lname')

ich teste damit nur die Inhalte der Variablen! In die Extension Base wird hier nicht geschrieben!
Wie der richtige Insert aussieht weiß ich nicht! Ist wie gesagt kein eigengestriktes Produkt? Kann ich das irgendwo herausfinden?

hoffe die Infos helfen etwas weiter...

gruß
Member: MadMax
MadMax Mar 20, 2010 at 13:45:44 (UTC)
Goto Top
Hallo freshToto,

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
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
Member: freshToto
freshToto Mar 22, 2010 at 21:39:30 (UTC)
Goto Top
Hallo Mad Max,
erstmal tausend dank für die Mühe die du dir gemacht hast!!!
Gibt es ne Möglichkeit das irgendwie zu prüfen ob der eintrag schon existiert wenn der trigger läuft!? oder kann man den trigger Zeitverzögert starten lassen oder sowas in der art?

Gruß
freshToto
Member: MadMax
MadMax Mar 22, 2010 at 21:58:49 (UTC)
Goto Top
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 face-smile

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
Member: freshToto
freshToto Mar 26, 2010 at 14:47:29 (UTC)
Goto Top
Hallo Mad Max,
sorry konnte es erst heute testen! Es funktioniert!!! Hatte die Hoffnung schon aufgegeben und dann war es doch so ein simpler Fehler!
Habe den Trigger jetzt für die Extension angelegt.

Tausend dank für deine Gedult und Mühe!!!

schönes Wochenende
Gruß
freshToto
Member: MadMax
MadMax Mar 26, 2010 at 18:52:29 (UTC)
Goto Top
Tja, mit Ruhm bekleckert hab ich mich auch nicht, das hätte ich auch eher merken können face-smile

Aber wenn es letztlich funktioniert, ist ja alles in Ordnung. Machst Du dann bitte noch ein Häkchen an dieses Thema face-wink

Dir auch ein schönes Wochenende.

Gruß, Mad Max