![]() |
Datenbank: MSDE • Version: Neueste • Zugriff über: TADO (MDAC 2.8)
Die zum Aktualisieren angegebene Zeile wurde nicht gefunden.
Hallo DPler,
ich hab mal wieder ein Mega-Problem an dem ich bereits einige Tage herumrätsele. Ich verwende zwei von mir geschriebene Programme, die miteinander Daten über den MSDE SQL- Server Daten austauschen. Der Ablauf ist so, dass das eine Programm, nennen wir es DatMan, aktuelle Zustände von Maschinen zyklisch in eine Tabelle stellt. Das andere Programm, nennen wir es DatWeb, schaut nun auch immer mal wieder in diese Tabelle. Sofern neue Datensätze (markiert über ein INT Feld) existieren, werden diese Daten als XML verschickt. Danach markiert DatWeb die Datensätze als "versendet". Ein weiterer Timer in DatWeb räumt alle verschickten Datensätze auf (Delete). Soweit der Ablauf. Nun kommt es in unregelmäßigen Abständen, teilweise tageweise, vor, dass DatMan die beliebte Meldung: "Die zum Aktualisieren angegebene Zeile wurde nicht gefunden...." hervorbringt. Diese Meldung wird sooft erzeugt, das wohl Windows den DatMan ohne jegliche Meldung beendet. Ich habe nach dieser Meldung auch schon gegoogelt - viel gelesen - nix verstanden. Die Meldung wird so wie es ausschaut von MDAC erzeugt und hat wohl was mit den Cursorn zu tun. Daraufhin habe ich alle TADOQuery und TADOConnections, und das sind sehr viele, auf folgende Eigenschaft geändert: CursorLocation: clUseServer LockType: ltOptimistic umgestellt. Daraufhin hat sich das Problem verschlimmert, aber es kommt nun die Meldung: "Fehler bei der Überprüfung auf vollständige Parallelität. Die Zeile wurde ausserhalb des Cursors geändert". Auch diese Meldung wird bis zum Absturz wiederholt. Jetzt bin ich auf der Suche 1. nach einer Erklärung? 2. einer Möglichkeit, wie ich herausbekomme, welche Query diese Meldung erzeugt? 3. was denn eigentlich für die Queries und Connections die optimale Einstellung der Eigenschaften überhaupt ist? Ich hoffe auf Hilfe Gruß Frank :oops: |
Re: Die zum Aktualisieren angegebene Zeile wurde nicht gefun
Hallo Frank,
das verursachende Statement kannst du zur Laufzeit leicht identifizieren, indem du die Queries in try except einfasst und ein log file führst. In der IDE genügt das Anhalten bei Sprach-Exceptions (Debugging-Optionen). Dein Fehler dürfte dadurch begünstigt werden, dass du Connection und Cursor länger als unbedingt nötig offen hältst. Vielleicht solltest du dein Konzept an der Stelle mal überprüfen. Bei konkurrierenden Zugriffen ist der Transaction Isolation Level sicher eine weitere Überlegung wert. Grüße vom marabu |
Re: Die zum Aktualisieren angegebene Zeile wurde nicht gefun
Hallo marabu,
erstmal Danke das Du Dich meinem Problem angenommen hast. Aber meinst Du mit "Transaction Isolation Level". Kannst Du mir dazu nähere Infos geben? Gruß Frank |
Re: Die zum Aktualisieren angegebene Zeile wurde nicht gefun
Hallo Frank,
die Eigenschaft TAdoConnection.IsolationLevel meine ich. Du findest in der Online-Hilfe reichlich Infos dazu. Die Einstellung steuert die Sichtbarkeit von Änderungen deines Clients für andere Clients. Wenn das Thema neu für dich ist, dann solltest du dir vielleicht ein Testprogramm schreiben (DBGrid, DBNavigator, RadioGroup für den IsolationLevel, AdoConnection, AdoDataSet), von dem du dann zwei Instanzen startest. Du könntest dann neben einem Literaturstudium ein wenig mit den Einstellungen spielen. Aber dein Hauptproblem sehe ich nicht in diesem Bereich und die Standardeinstellung "ReadCommitted" ist oft ausreichend, wenn Connection und Cursor nicht zu lange offen gehalten werden. marabu |
Re: Die zum Aktualisieren angegebene Zeile wurde nicht gefun
Hi marabu, hi Frank,
Vielleicht hilft es, wenn man weiss, wieso diese Meldung zustande kommt. Ich habe folgende Erfahrung gemacht: Wenn man eine DML-Operation ausführt (also UPDATE, INSERT, DELETE) dann erwartet ADO, das die MSDE folgende Meldung zurückgibt: "(1 row(s) affected)", also, das genau die Zeile verändert wurde. Wenn das nicht passiert, kommt ADO ganz schön durcheinander. Bei mir ist das passiert, weil ein Trigger in der Datenbank in einer anderen Tabelle einige Daten verändert hat. Da ich im Trigger kein 'SET NOCOUNT ON' an erster Stelle geschrieben habe, meldet die MSDE(Bei z.B. UPDATE FooBar SET Bla='X' Where ID = 1) : Zitat:
Nach meiner Einschätzung liegt das a) an so einem gemeinen Trigger, der ohne 'SET NOCOUNT ON' progrmamiert wurde. b) an einer 'Upateable View', die nicht genau die Meldung erzeugt '(1 row(s) affected)'. c) wirklich daran, das das zu aktualisierende Record so nicht mehr funktioniert Zu c) fällt mir noch etwas ein: Wenn Du eine TADOTable verwendest, dann erzeugt ADO beim UPDATE einen ziemlich bescheuerten Befehl:Die Tabelle TBL enthält 3 Spalten (ID,B und C, Primary Key sei ID). Das Update sieht nun so aus:
SQL-Code:
Wenn nun jemand gerade diese Zeile verändert hat (z.B. C=11111), dann klappt o.g. Statement einfach nicht mehr. Dann kommt nämlich zurück "(0 rows affected)" und DAS widerum erwartet ADO nicht und spuckt die verhaßte Meldung aus.
UPDATE TBL SET B='Foo' WHERE ID=0 AND B='Old Value' AND C=12345
Besser wäre doch soetwas:
SQL-Code:
Dann kann auch jemand Anderes die Zeile verändern (gut, Löschen geht nicht).
UPDATE TBL SET B='Foo' WHERE ID=0
Die berühmte Fehlermeldung habe ich im Zusammenhang mit dem TADOTable-Beispiel auch sporadisch bei einer Einzelplatzanwendung erlebt, und bisher kein Mittel dagegen gefunden. Außer, ich mache alle DML selbst, bastle mir also die UPDATE, INSERT und DELETE-Befehle selbst. Vielleicht helfen meine Erfahrungen mit dieser S****-Meldung ja weiter Schönes Wochenende! |
Re: Die zum Aktualisieren angegebene Zeile wurde nicht gefun
Hi alzaimar,
ich entsinne mich dunkel deine Ausführungen zum Thema SET NOCOUNT ON / OFF bereits in einem anderen thread gelesen zu haben. Es klingt sehr überzeugend. Hast du jemals eine Demo erstellt, mit der man das Phänomen nach Belieben reproduzieren kann? Ich frage deshalb, weil ich zwar auch einmal über diese spezielle Meldung gestolpert bin, allerdings bei der Beseitigung kein Trigger eine Rolle gespielt hatte. Meine aktuellen Programme laufen mit Triggern und seit mindestens fünf Jahren habe ich die Meldung nicht mehr gesehen. Was genau damals die Ursache war, daran erinnere ich mich leider nicht mehr. Auch dir ein schönes Wochenende marabu |
Re: Die zum Aktualisieren angegebene Zeile wurde nicht gefun
Liste der Anhänge anzeigen (Anzahl: 1)
Hi marabu,
Hier eine Demo mit Schema-Datei für MSSQL. Die Datenbank enthält eine Tabelle mit einem Trigger, der ein "0 rows affected erzeugt". Desweiteren eine "updateable View", die im "INSTEAD OF"-Trigger den gleichen Müll erzeugt. Trotzdem funktioniert das INSERT in beiden Fällen. Das Demo-Projekt enhält nur zwei Buttons, zwei TADOTable und eine ADO-Connection. Button#1 versucht, in die Table etwas einzufügen, Button#2 versucht, in die View etwas einzufügen. Das klappt nicht, bis man in den Triggern das "SET NOCOUNT ON" am Anfang einfügt. Bei der updateable View muss man zudem noch darauf achten, das der INSTEAD-OFF Trigger wirklich genau diese "x row(s) affected erzeugt", indem man nämlich irgendwo genau die Anzahl von Records einfügt, die verlangt sind. ADO ist da -wie schon erwähnt- sehr pingelig. Um den 3.Fall zu erzeugen, müsste man im Trigger nur einen der Felder nicht bzw. anders updaten und schon ballert die ADO diese Fehlermeldung raus. |
Re: Die zum Aktualisieren angegebene Zeile wurde nicht gefun
Vielen Dank für die Demo, alzaimar.
Grüße marabu |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz