![]() |
Datenbank: Firebird • Version: 2.1 • Zugriff über: UIB
Exception bei leerem Result
Eben habe ich eine herbe Überraschung erlebt, ich hoffe, es gibt eine Möglichkeit, das zu umgehen:
Ein Select Statement, für das die Ergebnismenge leer ist, weil zufällig auf keinen Datensatz die Where Klausel passt, liefert mir nicht kommentarlos eine leere Datenmenge zurück, sonder generiert eine Exception - Ich habe versucht, das zurückzuverfolgen, und festgestellt, dass die Exception anscheinend schon in der fbclient Dll ausgelöst wird. Eigentlich möchte ich nicht unbedingt für jeden Select-Befehl einen Try-except Block machen, bloss um ein leeres Ergebnis abzufangen. Es sollte doch laut Beschreibung der fetch Befehl false liefern, wenn keine Daten für das Fetch vorhanden sind. Gibt es da eine andere Lösung? |
AW: Exception bei leerem Result
Hört sich für mich nach einem Fehler der Zugriffskomponenten an. Was sagt der Hersteller dazu?
|
AW: Exception bei leerem Result
Da der Fehler bei anderen Zugriffskomponenten nicht zutrifft, würde ich auch auf einen Fehler in UIB Tippen. Da diese ja OS sind könntest du dort mal nachforschen
|
AW: Exception bei leerem Result
Hi!
Ohne UIB zu kennen, kann ich es mir fast nicht vorstellen, dass in einem so häufigen Fall eine Exception geworfen wird, und das bislang niemand angemerkt hat, sodass es korrigiert wurde. Bist du dir sicher, dass nicht vllt. dein Statement inkorrektes SQL beinhaltet oder sowas? Vllt. zeigst du mal etwas Code ;) Liebe Grüße, Frederic |
AW: Exception bei leerem Result
Zitat:
(Strg+C, wenn ein Delphi-Exception-Dialog den Fokus hat, und die Meldung ist im Zwischenspeicher) |
AW: Exception bei leerem Result
SQL-Code:
Dieser SQL-String wird an Execute übergeben (mit Cut and Paste aus dem Debugger kopiert, unmittelbar vor dem Aufruf von isc_dsql_execute2). Die Parameter name und user enthalten gültige Werte, allerdings gibt es in der Datenbank keine passenden Datensätze.
'select xleft,xtop,xwidth,xheight,titleheight,rowheight,widths from sysansicht where (name=?) and (user=?) and (Standard<>' ');'
Der Wert, den ich im Debugger als SQL-Statusrückgabewert angezeigt bekomme, ist 335544374. Die UIB Library produziert aber offenbar immer eine Exception, wenn dieser Statuscode ungleich 0 ist - der zugehörige Klartext der Exception lautet in dem Fall: 'Row not found for fetch, update or delete, or the result of a query is an empty table.' Das kann es doch eigentlich nicht geben? Ich meine, da ist ganz klar eine Fehlermeldung für die Situation vorgesehen, die doch in Wirklichkeit gar kein Fehler ist. Hat irgend jemand mit UIB diesbezüglich Erfahrung? |
AW: Exception bei leerem Result
greifst du vielleicht nach der Abfrage gleich auf den ersten Record zu, ohne zu prüfen, ob er existiert?
denn der Fehlercode ist ja: Zitat:
gibt es da ja z.B. das mysql_fetch_array(), was einen Record von einer Query holt. Wenn die Query aber keine Result-Sets hat, spuckt auch mySQL/php dort eine Exception heraus, da es ja keine Records gibt, deswegen muss man dort erstmal z.B. mit mysql_count_rows() abfragen, ob überhaupt Records als Ergebnis der Query vorhanden sind. Könnte das vielleicht die Ursache sein? Dass du versuchst, einen Record zu holen, obwohl es keinen gibt? Das ist alles nur eine Vermutung, da ich, wie gesagt, UIB nicht kenne... |
AW: Exception bei leerem Result
Hallo,
1. was sagt denn progdigy dazu ? 2. Probier mal CachedFetch=False ![]() 2. ist nur so ne Überlegung. Heiko |
AW: Exception bei leerem Result
Hallo,
Im Zitat von blackfin steckt die Lösung: Zitat:
Code:
Query.Eof gibt an, ob das Ende des Querys schon erreicht ist.
If not Query.Eof then
begin // Auswertung end; Ist Deine Abfrage leer, ist es immer true. Fuchtel |
AW: Exception bei leerem Result
Leider ist es nicht so. Ich glaube ich habe oben ziemlich genau beschrieben, was das Problem ist. Ich bekomme die Exception schon beim Ausführen der Query, noch bevor ich irgendwelche Daten mittels Fetch hole. Aber sogar das sollte möglich sein, in den von UIB mitgelieferten Demoprogrammen (der einzigen "Dokumentation") ist die Konstruktion
Delphi-Quellcode:
d.h. laut diesem UIB-DemoProgramm sollte, wenn keine Daten mehr da sind, einfach fetch den Wert false liefern.
(* Prepare the statement. *)
try UL.DSQLPrepare(DB, trans, stmt, sel_str, SQL_DIALECT, sqlda); except on E: Exception do begin WriteLn('Error: ',E.Message); ReadLn; raise; end; end; (* Execute the statement. *) UL.DSQLExecute(trans, stmt, SQL_DIALECT, nil); (* * Fetch and print the records. *) while UL.DSQLFetch(DB, trans, stmt, 1, sqlda) do Writeln(format('%s %s %s', [sqlda.AsString[0], sqlda.AsString[1], sqlda.AsString[2]])); Das ganze passiert nicht in Verbindung mit einer Query-Komponente, sondern ich verwende nur die Basisunit "UIBLib", das ist eine Unit, die ein paar Klassen zur direkten Verwendung der Firebird API zur Verfügung stellt. Das Statusergebnis <> 0, das "schuld" an der Auslösung der Exception in der UIB Unit ist, kommt direkt aus der Firebird-DLL fbclient.dll beim Execute der Query zurück. @heiko Ja, progdigy ist wohl eher der richtige Platz, um die Frage zu stellen. Ich bin jetzt schon so gewohnt, dass hier auf so ziemlich alles eine brauchbare Antwort kommt :) |
AW: Exception bei leerem Result
Delphi-Quellcode:
Ich kenn diese Komponente(nsammlung) zwar auch nicht, aber was passiert denn hierbei?
if UL.DSQLExecute(trans, stmt, SQL_DIALECT, nil) then
while UL.DSQLFetch(DB, trans, stmt, 1, sqlda) do Writeln(format('%s %s %s', [sqlda.AsString[0], sqlda.AsString[1], sqlda.AsString[2]])); (ich vermute mal DSQLExecute hat auch irgendeinen prüfbaren Rückgabewert) PS: Gibt es eventuell irgendwo sowas wie einstellbare Optionen, bei dieser Komponente? Wo man also einstellen kann, ob z.B. DSQLFetch eine Exception wirft oder nur False liefert. |
AW: Exception bei leerem Result
Ich habe jetzt das Problem einmal im progdigy Forum geposted.
Die Klasse TUIBLibrary hat mehrere execute Methoden, die sich in den zu übergebenden Parametern unterscheiden. Execute hat nur einen TParams Parameter, während Execute2 einen TParams und einen TResult Parameter hat. Ich war deshalb der Meinung, dass ich Execute2 verwenden muss, wenn ich ein Result erwarte - möglicherweise liegt da der Fehler, weil das Beispielprogramm verwendet execute und nicht execute2, und bekommt das Ergebnis im TParams zurück. Allerdings gibt es beim Beispielprogramm nicht gleichzeitig input und output Parameter. Ich werde jetzt in der Richtung weitersuchen, vielleicht komme ich doch noch drauf, wie es richtig geht :) Ich hatte gehofft, dass irgendwer hier diese Library verwendet und die Lösung weiss, aber so verbreitet scheint sie doch nicht zu sein. DSQLExecute ist eine procedure und hat keinen Rückgabewert. Das angeführte Codeschnipsel ist einem UIB Beispielprogramm entnommen, leider finde ich dort kein Beispiel, das einem SQL-Befehl Input Parameter übergibt und dann ein Resultset zurückgeliefert bekommt, sondern nur Beispiele mit SQL-Befehlen mit Parametern ohne Resultset und solche mit fixem SQL-Befehl mit Resultset, aber dafür ohne Parameter. |
AW: Exception bei leerem Result
Hallo, das Problem ist gelöst.
Die Firebird API kennt zwei verschiedene Execute Methoden, execute und execute2, und execute2 war die falsche :). Execute ist für Queries, die beliebig viele (zwischen 0 und n) Ergebniszeilen liefern, und hat keinen Result Parameter, weil die Ergebniszeilen danach mittels fetch der Reihe nach geholt werden müssen. Execute2 ist für Queries, die genau eine Zeile als Ergebnis zurückliefern, und dieser Wert wird in der Result Variablen übergeben. Wenn es kein Ergebnis gibt, löst execute2 eine Exception aus. Das Ganze ist, wie so vieles andere, nirgends richtig dokumentiert oder zumindest nicht so leicht zufinden, aber im progdigy Forum habe ich die Erklärungen bekommen. Der Hintergrund dazu ist im Firebird API Guide nachzulesen, wenn man dort gründlich danach sucht. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:37 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