AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken UnpreparedExecute führt SQL doppelt aus
Thema durchsuchen
Ansicht
Themen-Optionen

UnpreparedExecute führt SQL doppelt aus

Ein Thema von himitsu · begonnen am 7. Aug 2014 · letzter Beitrag vom 9. Aug 2014
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.149 Beiträge
 
Delphi 12 Athens
 
#1

UnpreparedExecute führt SQL doppelt aus

  Alt 7. Aug 2014, 18:41
Datenbank: postgres • Version: 9.0 • Zugriff über: PgDAC
Moin,

weiß zufällig jemand, warum PgDAC das SQL doppelt ausführt, wenn UnpreparedExecute aktiviert ist?

Beispiele: Ein SELECT pg_sleep(15) dauert 30 Sekunden
und ein DROP FRUNCTION Test(); knall mit "existiert nicht", da das beim zweiten Durchlauf natürlich nicht mehr existiert.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#2

AW: UnpreparedExecute führt SQL doppelt aus

  Alt 8. Aug 2014, 07:47
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:
Remarks

If the UnpreparedExecute propery is set to True, the simple execute is used for SQL statement. Statement is not prepared before execute. It allows to add multiple statements separated by semicolon to the SQL property.
Insbesonderes das "..mehrere Statements getrennt durch Semicolon.." hat mich überrascht und auf die Idee gebracht.
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.149 Beiträge
 
Delphi 12 Athens
 
#3

AW: UnpreparedExecute führt SQL doppelt aus

  Alt 8. Aug 2014, 13:39
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:
DROP FRUNCTION Test(VARCHAR);
CREATE FUNCTION Test(INTEGER)
...;
UnpreparedExecute=False und es funktioniert meistens, erlaubt dann aber keine SQL-Scripte mehr.
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 SELECT pg_sleep(5) dauert 10 Sekunden, aber ein SELECT pg_sleep(5), 1 nur 5.
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).
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 8. Aug 2014 um 14:26 Uhr)
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#4

AW: UnpreparedExecute führt SQL doppelt aus

  Alt 8. Aug 2014, 16:12
schau mal hier unter 1.10.0.6 27-May-09:
http://www.devart.com/pgdac/revision_history.html

sieht nach Idee 1 aus.
Allerdings ist das schon recht alter Kram. Ist Dein Treiber so alt? Oder haben sie den Bug redeployed?
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.149 Beiträge
 
Delphi 12 Athens
 
#5

AW: UnpreparedExecute führt SQL doppelt aus

  Alt 8. Aug 2014, 17:33
Ist eine 4.3.7, meinte grade der Einstellungsdialog an der PgConnection.

sieht nach Idee 1 aus.
Allerdings ist das schon recht alter Kram. Ist Dein Treiber so alt? Oder haben sie den Bug redeployed?
Sieht danach aus, vielleicht hatten die den auch zweimal drin und nur das erste Vorkommen behoben, oder doch für mich wieder eingebaut.

Zitat:
4.1.3 18-Sep-13
Bug when UnpreparedExecute option is set to True is fixed
Wobei Dieses eigentlich auch nicht schlecht klingt, aber sollte ebenfalls schon drin sein.



Schön ist auch der Fehler darüber.
Zitat:
Fixed bug with string fields longer than 65535
DevExpress dreht gern voll durch, wenn VARCHAR-Felder, ohne Längenangabe, rüberkommen, denn PgDAC behauptet dann das Feld sei 16 KB groß (8192 Chars), aber da VARCHAR dennoch mehr enthalten kann, rauchen dann die DBGrids ab und nehmen das Programm mit wenn doch mal mehr als 8191 Zeichen in soeinem Feld drin stecken.



Hab mich nochmal bissl durchgekämpft.

bei SELECT pg_sleep(15), 1 :
Code:
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
...
bei SELECT pg_sleep(15) :
Code:
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
...
30 sec mit Unpepared=True
SELECT pg_sleep(15) 15 sec mit Unpepared=False
SELECT pg_sleep(15) 15 sec
SELECT pg_sleep(15), 1 Liefert ein "Unexpected server response" und danach ist die ganze Connection futsch.
SQL-Code:
SELECT COALESCE(pg_sleep(15), '')

-- oder
SELECT pg_sleep(15);
SELECT 1;
Doppelt mit Unpepared=True => liefert den "function does not exists"-Fehler (wurde ja schon im ersten Durchlauf gelöscht)
DROP FUNCTION Test() Einfach mit Unpepared=False
DROP FUNCTION Test()
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#6

AW: UnpreparedExecute führt SQL doppelt aus

  Alt 8. Aug 2014, 20:18
Die 'COALESCE' Funktion führt Funktionen in einigen RDBMS doppelt aus, denn sie ist implementiert als
Code:
function Coalesce (a,b,...)
  if invoke(a) != null then return invoke(a)
  else if ...
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.

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.

Geändert von Dejan Vu ( 8. Aug 2014 um 20:30 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.149 Beiträge
 
Delphi 12 Athens
 
#7

AW: UnpreparedExecute führt SQL doppelt aus

  Alt 8. Aug 2014, 20:38
Am Besten wäre es, wenn das garnicht erst doppelt ausführt.
Und das mit dem "nach Typ sehen" ... dann sollte doch SELECT pg_sleep(15) genauso wie SELECT pg_sleep(15), 1 ausgeführt werden, was es aber nicht tut.

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 DROP irgendwas oder CREATE irgendwas aufgefallen, wo es dann so schön knallt.


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ß.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 8. Aug 2014 um 20:45 Uhr)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#8

AW: UnpreparedExecute führt SQL doppelt aus

  Alt 9. Aug 2014, 10:27
Alter Schwede, verzwickt. Ich passe.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.149 Beiträge
 
Delphi 12 Athens
 
#9

AW: UnpreparedExecute führt SQL doppelt aus

  Alt 9. Aug 2014, 10:45
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 SELECT SpeichereVaiable('abc', LeseVariable('abc') + 1) die Variable doppelt hochgezählt hat. (eine 'ne Tabelle mit Name- und Wert-Spalte)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 9. Aug 2014 um 10:48 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz