[GELÖST] OnDelete und Modify bei SQL-Server???

25. Februar 2015 10:06

Hallo Leute,

ich habe ein Problem, welches ich dringend lösen sollte, momentan aber keine wirklich gute Lösung finde!

Es geht um eine Dynamics NAV 2009 Umgebung, letzte Build No., welche neu auf SQL 2012 läuft.

Dabei wird in einer Tabelle "Vehicle Customer" im OnDelete Trigger in der Tabelle "Vehicle" ein Feld updated:

OnDelete Trigger Tabelle "Vehicle Customer":

Code:
OnDelete()
IF (Type = Type::"Warranty Add-On") AND Vehicle.GET(VIN) THEN BEGIN
  Vehicle."Warranty Add-On Contract Type" := '';
  Vehicle.MODIFY;
END;


Das heisst, wenn der Datensatz in der Tabelle "Vehicle Customer" gelöscht wird, wird in der Tabelle "Vehicle" das Feld "Warranty Add-On Contract Type" auf blank gesetzt.
Dies funktioniert auch einwandfrei und ist sicher Standard.

In der Tabelle "Vehicle" wird aber im OnDelete Trigger die Tabelle "Vehicle Customer" auch angewendet:

OnDelete Trigger Tabelle "Vehicle":

Code:
OnDelete()
VehCustomers.RESET;
VehCustomers.SETRANGE(VIN,VIN);
VehCustomers.DELETEALL(TRUE);


Das heisst, wenn der Datensatz in der Tabelle "Vehicle" gelöscht wird, wird der OnDelete Trigger der Tabelle "Vehicle Customer" aufgerufen und die Datensätze gelöscht.
Dies funktioniert auch einwandfrei mit der native Datenbank (NAV5 oder NAV2009)!

Wird nun aber eine SQL-Datenbank anstelle der native Datenbank verwendet, erhalte ich die folgende/beiliegende Fehlermeldung:

25-02-2015 08-54-54.gif


Ein anderer Benutzer hat...

Dies geschieht aber nur mit der SQL-Datenbank, mit den native Datenbanken erhalte ich keine Fehlermeldung.

Ich stehe nun gerade ein wenig "auf dem Schlauch"!?! Weil das Vorgehen an und für sich ja korrekt wäre.

Ich weiss nun nicht, wie ich nun prüfen sollte,
- ob nur ein Datensatz in der Tabelle "Vehicle Customer" gelöscht wurde und dann das Feld in der Tabelle "Vehicle" geändert werden soll (MODIFY)
- oder ob der Datensatz der Tabelle "Vehicle" inklusive der Datensätze der Tabelle "Vehicle Customer" gelöscht werden und dann der MODIFY auf die Tabelle "Vehicle" gar nicht mehr nötig ist

Kann da etwas auf dem SQL-Server/der SQL-Datenbank eingestellt werden? Oder muss ich hier mit Parametern arbeiten, welche ich vorgängig übergebe?
Solche Probleme können aber dauernd auftreten.

Vielen Dank für rasche Hilfe!!!
Beno
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Zuletzt geändert von beno am 26. Februar 2015 18:04, insgesamt 1-mal geändert.

Re: OnDelete und Modify bei SQL-Server???

25. Februar 2015 10:19

Interessant, ich wusste gar nicht, dass die native DB da anders tickt bzw. anders getickt hat.

Es gibt zwei Arten, das Problem zu lösen, ohne Geschäftslogik einzubüßen
  1. Schnelle Lösung: VehCustomers.DELETEALL(TRUE); durch VehCustomers.DELETEALL; ersetzen. Ist nicht ganz sauber, da "Vehicle Customer".OnDelete weiteren Code enthalten kann, welcher evtl. sehr wohl ausgeführt werden sollte.
  2. Saubere Lösung: Der Tabelle "Vehicle Customer" eine globale boolean-Variable und eine neue Funktion spendieren, z.B. namens DoNotUpdateVehicle (oder auch CalledByVehicleOnDelete). Die Funktion setzt die Variable.
    Den zitierten Quelltext von "Vehicle Customer".OnDelete nur dann ausführen, wenn DoNotUpdateVehicle = FALSE ist.
    In Vehicle.OnDelete vor dem VehCustomers.DELETEALL(TRUE); die neue Funktion zum Setzen (=TRUE) der Variablen aufrufen.

Re: OnDelete und Modify bei SQL-Server???

25. Februar 2015 11:53

Hi,

der Fehler tritt auf, da du den zu löschenden Datensatz aus der Tabelle Vehicle gerade im Zugriff hast, aber gleichzeitig ein Feld daran (über tabelle Vehicle customer) über einen zweiten Zeiger ändern willst.
Irgendwie entzieht sich mir der Sinn. Du löscht einen Datensatz, willst aber vorher noch ein Feld daran geändert haben, ohne zu validieren?
Also evtl. den Datensatz im OnDelete trigger vor dem Aufruf der Vehcustomers.deleteall(true) per DELETE löschen, dann dürfte auch das vehicle.get(vin) nicht mehr greifen.

gruß

Re: OnDelete und Modify bei SQL-Server???

25. Februar 2015 14:23

Hallo Jörg,

Wenn Du nur den Datensatz in der Tabelle "Vehicle Customer" löscht, mach dieser Code sehr wohl Sinn.
Wenn nur der Datensatz in der Tabelle "Vehicle Customer" gelöscht wird, dann soll in der Tabelle "Vehicle" das entsprechende Feld verändert werden.

Wenn dann aber umgekehrt der Datensatz in der Tabelle "Vehicle" inklusive aller Relations zu Tabellen gelöscht wird, dann macht der Code natürlich keinen Sinn mehr.
Da der Datensatz in der Tabelle "Vehicle" gelöscht wird, muss das Feld auch nicht mehr verändert werden. Der OnDelete Trigger der Tabelle "Vehicle Customer" versucht es
dann aber logischerweise trotzdem!

Aber wer denkt beim Hinzufügen von Code im OnDelete Trigger einer Tabelle schon daran, dass dies dann plötzlich zu Problemen führen kann.
Vor allem, weil dies in der nativen Umgebung in allen Versionen kein Problem darstellt. Nur im Zusammenhang mit SQL gibt es das Problem.

Ich denke, Natalie's Vorschlag macht am Meisten Sinn.

Gruss, Beno

OnDelete und Modify bei SQL-Server???

26. Februar 2015 18:04

Hallo Natalie,

das mit der Funktion innerhalb der Tabelle hat leider nicht funktioniert. Ich kann zwar Werte (z.B. TRUE) an eine solche Funktion übergeben und in einer globalen Variablen abspeichern. Aber...
wenn ich dann den OnDelete Trigger dieser Tabelle aufrufe, ist die globale Variable leer bzw. FALSE...

Ich musste es so lösen, dass ich im OnDelete Trigger der Tabelle "Vehicle", NACH dem VehCustomers.DELETEALL(TRUE) nochmals einen Rec.GET durchführte.
Es tritt nun kein Fehler mehr auf.

Vielen Dank, Beno

Re: OnDelete und Modify bei SQL-Server???

26. Februar 2015 19:03

Falls es dich trotz der bereits gefundenen Lösung interessiert:

beno hat geschrieben:Ich kann zwar Werte (z.B. TRUE) an eine solche Funktion übergeben und in einer globalen Variablen abspeichern. Aber...
wenn ich dann den OnDelete Trigger dieser Tabelle aufrufe, ist die globale Variable leer bzw. FALSE...
Dann stimmt da noch etwas nicht. Zeig mal bitte deinen Quelltext.

Re: OnDelete und Modify bei SQL-Server???

6. März 2015 15:57

beno hat geschrieben:das mit der Funktion innerhalb der Tabelle hat leider nicht funktioniert. Ich kann zwar Werte (z.B. TRUE) an eine solche Funktion übergeben und in einer globalen Variablen abspeichern. Aber...
wenn ich dann den OnDelete Trigger dieser Tabelle aufrufe, ist die globale Variable leer bzw. FALSE...


Wenn du mit globalen Variablen im OnDelete arbeiten möchtest, dann darfst du kein DELETEALL(TRUE) verwenden, sondern musst mit Hilfe einer Schleife jeden Datensatz mit DELETE(TRUE) löschen. Dann wird die globale Variable auch nicht geleert.