![]() |
Datenbank: postgres • Version: 9.0 • Zugriff über: PgDAC
UnpreparedExecute führt SQL doppelt aus
Moin,
weiß zufällig jemand, warum PgDAC das SQL doppelt ausführt, wenn ![]() Beispiele: Ein
Delphi-Quellcode:
dauert 30 Sekunden
SELECT pg_sleep(15)
und ein
Delphi-Quellcode:
knall mit "existiert nicht", da das beim zweiten Durchlauf natürlich nicht mehr existiert.
DROP FRUNCTION Test();
|
AW: UnpreparedExecute führt SQL doppelt aus
3 abstruse Ideen:
1. der Treiber ist fehlerhaft. 2. Du hast versehentlich eine doppelte Ausführung programmiert (event, ..) 3. Es gibt in sqlplus (oracle) ein Zeichen, das Statement auszuführen bzw. das letzte abgesetzte Select wiederholt(!) aufzurufen. Weiß nicht, ob sowas bei pg bzw. dem Treiber evtl auch unterstützt wird. Hast Du mglw versehentlich solche Zeichen ";", "/" ... am Ende des Statements? Die Idee zu 3 hatte ich durch den Hilfetext Zitat:
|
AW: UnpreparedExecute führt SQL doppelt aus
In dem Sleep-Beispiel ist kein ; am Ende, aber das ist natürlich möglich, denn das UnpreparedExecute erlaubt ja grade mehrere Befehle, welche via ; getrennt sind.
SQL-Code:
UnpreparedExecute=False und es funktioniert meistens, erlaubt dann aber keine SQL-Scripte mehr.
DROP FRUNCTION Test(VARCHAR);
CREATE FUNCTION Test(INTEGER) ...; Und jenachdem, ob es einen Fehler gibt (Fehlermeldung im/vom DB-Server), wird das auch manchmal doppelt ausgeführt. Hatte mal versucht das zu debuggen, aber fand die Stelle nicht. Ich entdeckte zwar eine Stelle, wo es heißt "wenn der und der Fehler, dann mach nochmal", aber die war es doch nicht, vorallem da es auch passiert, wenn es keine Fehler gab. [add] Lauf SQLMonitor an der Connection wird es nur einmal ausgeführt. [add2] Und das Schlimme ist ja, daß es nicht immer passiert. Ein
Delphi-Quellcode:
dauert 10 Sekunden, aber ein
SELECT pg_sleep(5)
Delphi-Quellcode:
nur 5.
SELECT pg_sleep(5), 1
Vermutlich hängt das mit der Art und Anzahl der Datensätze im Result zusammen. Ein Execute mit DROP FUNCTION wird nur einmal ausgeführt und ein Open ist doppelt (vermutlich da kein Result). |
AW: UnpreparedExecute führt SQL doppelt aus
schau mal hier unter 1.10.0.6 27-May-09:
![]() sieht nach Idee 1 aus. Allerdings ist das schon recht alter Kram. Ist Dein Treiber so alt? Oder haben sie den Bug redeployed? |
AW: UnpreparedExecute führt SQL doppelt aus
Ist eine 4.3.7, meinte grade der Einstellungsdialog an der PgConnection. :angle:
Zitat:
Zitat:
Zitat:
Zitat:
Hab mich nochmal bissl durchgekämpft. bei
Delphi-Quellcode:
:
SELECT pg_sleep(15), 1
Code:
bei
dac150.MemData.TData.Open ===> einmal Ausführen
dac150.MemDS.TMemDataSet.InternalOpen dac150.DBAccess.TCustomDADataSet.InternalOpen :5071fd43 TDataSet.DoInternalOpen + $1F dac150.DBAccess.TCustomDADataSet.OpenCursor(False) :5071fcb7 TDataSet.SetActive + $5B dac150.DBAccess.TCustomDADataSet.SetActive(???) :5071fafe TDataSet.Open + $A ...
Delphi-Quellcode:
:
SELECT pg_sleep(15)
Code:
30 sec mit Unpepared=True
dac150.MemData.TData.Open ===> nochmal Ausführen
:02074a05 TPgSQLCommand.ReadOutParams + $335 :02074627 TPgSQLCommand.DescribeParams + $5B :02073918 TPgSQLCommand.SetProp + $30 dac150.CRAccess.TCRRecordSet.ExecCommand :020752d1 TPgSQLRecordSet.InternalCreateComplexField + $C9 dac150.CRAccess.TCRRecordSet.ExecFetch(???) dac150.CRAccess.TCRRecordSet.InternalOpen(False) :02076b79 ReadBlobs + $15 dac150.MemData.TData.Open ===> einmal Ausführen dac150.MemDS.TMemDataSet.InternalOpen dac150.DBAccess.TCustomDADataSet.InternalOpen :5071fd43 TDataSet.DoInternalOpen + $1F dac150.DBAccess.TCustomDADataSet.OpenCursor(False) :5071fcb7 TDataSet.SetActive + $5B dac150.DBAccess.TCustomDADataSet.SetActive(???) :5071fafe TDataSet.Open + $A ...
SQL-Code:
15 sec mit Unpepared=False
SELECT pg_sleep(15)
SQL-Code:
15 sec
SELECT pg_sleep(15)
SQL-Code:
Liefert ein "Unexpected server response" und danach ist die ganze Connection futsch.
SELECT pg_sleep(15), 1
SQL-Code:
Doppelt mit Unpepared=True => liefert den "function does not exists"-Fehler (wurde ja schon im ersten Durchlauf gelöscht)
SELECT COALESCE(pg_sleep(15), '')
-- oder SELECT pg_sleep(15); SELECT 1;
SQL-Code:
Einfach mit Unpepared=False
DROP FUNCTION Test()
SQL-Code:
DROP FUNCTION Test()
|
AW: UnpreparedExecute führt SQL doppelt aus
Die 'COALESCE' Funktion führt Funktionen in einigen RDBMS doppelt aus, denn sie ist implementiert als
Code:
Nur so als Hinweis. Ich kann mir auch vorstellen, das bei einem "SELECT Foo" zuerst das Format abgefragt wird: 'Wat is dat denn für eine Datentyp'?. Normale SELECT werden natürlich nicht ausgeführt, aber vielleicht so eine Funktion. Das wäre die Erklärung, weshalb das 'unprepared' doppelt ausgeführt wird: 1x zum Ermitteln des Datentyps und 1x bei der Ausführung.
function Coalesce (a,b,...)
if invoke(a) != null then return invoke(a) else if ... Vielleicht kannst Du das mit einem 'SELECT 0 union SELECT pg_Sleep(15)' umgehen, denn dann wird vielleicht nur das 1.Select bei der Datentypermittlung ausgewertet. |
AW: UnpreparedExecute führt SQL doppelt aus
Am Besten wäre es, wenn das garnicht erst doppelt ausführt.
Und das mit dem "nach Typ sehen" ... dann sollte doch
Delphi-Quellcode:
genauso wie
SELECT pg_sleep(15)
Delphi-Quellcode:
ausgeführt werden, was es aber nicht tut. :gruebel:
SELECT pg_sleep(15), 1
Das COALESCE war einfach mal ein Versuch, in dem einen praxsisfernen TestSQL auszuprovieren, was passiert, wenn man die Funktion in einer Anderen versteckt, mit dem Ergebnis, daß es noch schlimmer wurde. Schlimm ist ja, daß man oft garnicht erkennen kann, ob es doppelt ausgeführt wird. Womit man jetzt noch garnicht weiß, ob und wieviele sonstige Abfragen eigentlich doppelt so schnell wären. Mir ist es eben schon bei Funktionen ala
Delphi-Quellcode:
oder
DROP irgendwas
Delphi-Quellcode:
aufgefallen, wo es dann so schön knallt.
CREATE irgendwas
Im PgAdmin kann man ein SQL ausführen, indem man einfach auf Play drückt und fertig. Im Code tut man zwar oft entscheigen, ob man nur ein Execute macht, oder ein Open mit auslesen des Results, aber an vielen Stellen wird einfach irgendein SQL ausgeführt, ohne daß man jetzt schon weiß wie das mal aussieht und es gibt im Programm auch eine Edit-Oberfläche, wo es jetzt mehrere Buttons gibt (für Open, Execute und Sonderformen), wo es eigentlich recht praktisch wäre, wenn es da auch mal weniger Buttons gibt, für die man sich entscheiden muß. |
AW: UnpreparedExecute führt SQL doppelt aus
Alter Schwede, verzwickt. Ich passe.
|
AW: UnpreparedExecute führt SQL doppelt aus
Zum Glück scheint es so, daß an den wichtigen Stellen nicht doppelt gerechnet (addiert) wird, zumindestens nicht so, daß es aufeinander aufbaut, sonst wären (hoffentlich) schon irgendwo Probleme mit den Ergebnissen aufgefallen.
Aber ich hatte schonmal einen Fall, wo ein
Delphi-Quellcode:
die Variable doppelt hochgezählt hat. (eine 'ne Tabelle mit Name- und Wert-Spalte)
SELECT SpeichereVaiable('abc', LeseVariable('abc') + 1)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:24 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 by Thomas Breitkreuz