Hallo Delphi-Gemeinde,
ich habe eine Anwendung geschrieben, welche mittler weile seit über 10 Jahren mehr oder weniger erfolgreich läuft. Eher mehr
Ich nutze zum Erstellen der Primärschlüssel eine eigene Funktion, welche aus einer Primärschlüssel-Tabelle einen Integer-Wert ermittelt, diesen um Eins hoch zählt ... usw.
Die AutoIdent-Funktion des
MsSQL-Servers nutze ich nicht, da meine Anwendung teilweise auch auf anderen Datenbanken (z.B. dBase, Clipper ...) läuft, welche AutoIdent-Funktionen nicht kennen.
Zum Löschen von Datensätzen gibt es in meiner Anwendung eine Regel: Der Primärschlüssel wird negativ gesetzt und somit ist der Datensatz als gelöscht markiert. Kunden-Anforderung! (Aufgeräumt wird später).
Code:
UPDATE tabelle SET id=ABS(id)*-1 WHERE id=:ID;
TransactionLook ist aktiviert.
Mit dieser Regel läuft meine Anwendung seit Anfang an eigentlich recht stabil.
Mittlerweile ist meine Anwendung soweit fortgeschritten, dass es in einigen Kundeninstallationen einen Primärschlüssel im 5 Mio-Bereich verwendet. Und natürlich ist die Anwendung mittlerweile so groß, dass es sehr schwer ist,
SQL-Fehler zu identifizieren. Voll allem dann, wenn es sich um einen Folgefehler handelt.
Das Problem: Der
SQL-Befehl:
Code:
UPDATE tabelle SET id=ABS(id)*-1 WHERE id=:ID;
, wobei ID mit "5366038" belegt ist, schlägt fehl, da ein doppelter Primärschlüssel nicht zugelassen ist.
Das heißt, es soll eine Datensatz gelöscht markiert werden, welcher bereits gelöscht markiert ist. Und tatsächlich existiert zwei Datensätze, jeweils mit einem positiven ID und einem "gleichen" negativen ID. Das das nicht klappt ist klar.
Interessanter Weise tritt dieser Fehler NUR im
MSSQL-2008R2 und
MSSQL-2012 auf und immer bei den gleichen Schlüsseln 5366038 bzw. 5365874.
Ich habe ca. 20 Installationen am laufen, die diesen Fehler produziert haben. Und es betrifft immer einen dieser beiden Schlüssel.
Ich habe das ganze Programm durchwühlt und nach einer Ursache im Code gesucht, konnte aber nichts finden.
Aber Tatsache, dass dieser Fehler immer bei den gleichen IDs auftritt, bringt mir zu der Überzeugung, dass der Fehler nicht in meinem Programm-Code zu suchen ist, sondern wo anders.
Von Visual Studio 20xy MFC-Klassen kenne ich das Phänomen, dass dort ein Integer-Wert festgelegt wurde, welcher quasi als NULL definiert ist. Das war ein Bug von M$, welcher irgendwie gefixt wurde.
So soll (wenn ich das richtig verstanden haben) der (z.B.)
SQL-Befehl:
Code:
UPDATE tabelle SET id=ABS(id)*-1 WHERE id=5365874;
vom
MSSQL-Server als
Code:
UPDATE tabelle SET id=ABS(id)*-1 WHERE id =NULL;
übersetzt/interpretiert worden sein.
Kann es sein, dass in den Delphi-
ADO-Klassen ein ähnliches Phänomen existiert?
Meine
IDE: Delphi-2009 auf MS-Server 2008-R2.
Die Parameter (:ID) werden mit SetParam gesetzt, nicht direkt im
SQL-Statement.
Die Verbindung zum
SQL-Server wird über einen eigenen ConnectionString per SQLOLEDB aufgebaut.
Habt ihr ähnliche Erfahrungen?