SQL-Statement für MySql anders als für SQLite?

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

SQL-Statement für MySql anders als für SQLite?

Beitrag von Aliobaba »

Hallo,

ich habe eine kleines "Datenbank-Übungsprogramm" geschrieben, das ich wahlweise auf MYSql oder auf SQLite zugreifen lassen kann.
Alles (Neueingabe von Daten, der Update-Befehl, die Suchfunktion) funktioniert auch soweit sehr gut - allerdings ist es eigenartig, dass diese Zeile:
-> sql.Add(' LIMIT 1' );
nur bei SQLite eine Fehlermeldung produziert, nicht aber beim Absetzen dieses Statements an MYSql. Beim Auskommentieren dieser Zeile funktioniert das Löschen auch bei SQLite (natürlich ohne "LIMIT").

MmVisual hat mich mehrmals darauf hingewiesen, beim Erstellen des Statements dies hier http://www.sqlite.org/lang_delete.html" onclick="window.open(this.href);return false; zu beachten, was ich - wie ich meine - auch tat. Und wie gesagt, diese Procedur funktioniert ja auch bei MYSql problemlos.

Warum nur nicht unter SQLite ?? Verschiedene "Sprachdialekte"?

Aliobaba

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Code: Alles auswählen

procedure TForm1.LoeschenClick(Sender: TObject);
Var
   x : string;
begin
 x :=DBEdit1.Text;
 with ZQuery1 do
  begin
//   ZQuery1.Delete;    //   das geht auch!!
     sql.Text := 'DELETE FROM `tabelle1` WHERE  Column1= :col1 ';
     sql.Add(' LIMIT 1' );
     ParamByName('Col1').AsString := x;
     ExecSQL;
   Close;
  end;
Leereedit;
end;
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6765
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: SQL-Statement für MySql anders als für SQLite?

Beitrag von af0815 »

Ja, es gibt tatsächlich verschiedene Dialekte, wobei meistens eine vereinbarte Grundmenge funktioniert. ZB SQL 92 , SQL 2008,... Siehe auch hier http://de.wikipedia.org/wiki/SQL. Limit wirst du nicht in diesen standartsierten Befehlen finden, bz. Wenn das eine System SQL 92 unterstützt und das andere SQL 2008, so werden nicht alle Befehle gleich sein. Das zu den Dialekten von SQL.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Keifor
Beiträge: 31
Registriert: Sa 28. Aug 2010, 15:15
OS, Lazarus, FPC: pc-linux-gnu - Funtoo stable, L trunk, FPC trunk
CPU-Target: i686/x86_64

Re: SQL-Statement für MySql anders als für SQLite?

Beitrag von Keifor »

Mehr verschiedene Varianten verschiedener Dialekte :mrgreen: . Es sind nicht nur die unterschiedlichen Standards sondern auch die Implementation.
Die verschiedenen Implementation in Mysql, MSSQL, SQLITE, Postgresql, Oracle, usw. sind jeweils mehr oder minder Standard Konform mit einem Dialekt, weichen darüber hinaus aber auch noch mit selbst implementierten Teile oder Beschränkungen ab. Bei den gängigen sind sie meist Konform (einfaches SELECT,UPDATE,DROP,.., WHERE klausel usw.) aber bei den erweiterten Anfragen gehen sie dann auseinander was entweder gar nicht funktioniert oder in verschiedenen Implementation zu stark unterschiedlicher Performance führt. (Bspw. Nested Selects, Handhabung verschiedener Links/Rechts/Kreuz Verknüpfungen, Stored *, Handhabung von Views ...)

Zur primären Frage:
Aliobaba hat geschrieben: MmVisual hat mich mehrmals darauf hingewiesen, beim Erstellen des Statements dies hier http://www.sqlite.org/lang_delete.html" onclick="window.open(this.href);return false; zu beachten, was ich - wie ich meine - auch tat. Und wie gesagt, diese Procedur funktioniert ja auch bei MYSql problemlos.
Ich vermute mal was MmVisual meinte ist folgendes:

In der Beschreibung (angegebener link für sqlite Delete Anweisung) steht das ORDER BY / LIMIT dann erlaubt sind, wenn SQLITE_ENABLE_UPDATE_DELETE_LIMIT beim Übersetzen der Bibliotheken genutzt wird. Klickt man drauf, kommt man zu der Beschreibung und der schönen Überschrift:
"1.4 Options To Enable Features Normally Turned Off", zu deutsch: Optionen um Features zu aktivieren, die Normal nicht aktiviert sind.
In der Beschreibung selbst steht drin, dass um das Feature zu aktivieren die Bibliothek selbst gebaut werden muss (mit aktiviertem Feature) und gegebenenfalls noch lemon (parser generator, ebenfalls damit).

Ich vermute weiterhin, das du die Standard (binär Distribution oder Standard konfigurierte) Bibliothek nutzt. Ergo, kein Update/Delete Limit Support.

Wenn nicht, dann wäre die Fehlermeldung nett.
Zuletzt geändert von Keifor am Mi 23. Mai 2012, 20:06, insgesamt 1-mal geändert.

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: SQL-Statement für MySql anders als für SQLite?

Beitrag von Aliobaba »

Danke!

Aber eigenartig ist das ja schon, dass der vom mir gepostete Code doch mit der von SQLite geforderten Ausdrucksweise ( http://www.sqlite.org/lang_delete.html" onclick="window.open(this.href);return false; ) konform geht, - - - aber bei Anfragen an eine MySql-Datenbank funktioniert's, bei einer SQLite-Datenbank nicht.

Was mache ich falsch? "LIMIT" ist laut Doku von SQLite möglich!

Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: SQL-Statement für MySql anders als für SQLite?

Beitrag von Aliobaba »

... uups, jetzt haben sich die Antworten überschnitten.

Die Fehlermeldung lautet:

Projekt "xy" hat Exception-Klasse "EZSQLException" ausgelöst mit der Meldung:
SQL Error: near "LIMIT":syntax error

In Datei 'C:\lazarus\components\eosDBO\src\dbc\ZDbcSqLiteUrils.pas' in Zeile 248
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Socke
Lazarusforum e. V.
Beiträge: 3177
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: SQL-Statement für MySql anders als für SQLite?

Beitrag von Socke »

Aliobaba hat geschrieben:SQL Error: near "LIMIT":syntax error
Da steht doch, dass dein SQLite nicht mit LIMIT klar kommt.
Aliobaba hat geschrieben:"LIMIT" ist laut Doku von SQLite möglich!
Auf welche Dokumentation beziehst du dich? Ich zitiere http://www.sqlite.org/lang_delete.html
SQLite3 Dokumentation hat geschrieben:If SQLite is compiled with the SQLITE_ENABLE_UPDATE_DELETE_LIMIT compile-time option, then the syntax of the DELETE statement is extended by the addition of optional ORDER BY and LIMIT clauses:
Da steht ganz klar: Das geht nur, wenn das beim Übersetzen von SQLite bereits aktiviert wurde. Ansonsten -- also auch bei den offiziellen Binärprogrammen -- geht das nicht. (siehe auch oben).

Als Fazit mögliche Lösungen:
  • Übersetze dir SQLite3 selbst
  • Entwerfe dein Datenmodell so, dass du kein LIMIT brauchst.

    Wie stellst du denn sonst sicher, dass der richtige Datensatz gelöscht wird?
Zuletzt geändert von Lori am Do 24. Mai 2012, 19:29, insgesamt 1-mal geändert.
Grund: Highlighter
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: SQL-Statement für MySql anders als für SQLite?

Beitrag von Aliobaba »

Hallo Socke,

Danke!
Das habe ich in der Doku nicht richtig verstanden, sorry!
Ist für einen Anfänger aber wohl auch erst Lektion 2 - und das Selber Kompilieren von SQLite kommt sicher erst im "Fortgeschrittenen-Kurs" vor. :oops:

Mich hat das Thema einfach ganz grundsätzlich interessiert.

Ich werde dann natürlich die von MmVisual vorgeschlagene Lösung (sh. unten) verwenden. Ich wollte halt nur ein wenig über den Tellerrand sehen. Schadet ja nie

Wie stellst du denn sonst sicher, dass der richtige Datensatz gelöscht wird?

Alternativ könnte man ja in der "Where-Anweisung" den Datensatz noch ganz exakt eingrenzen.

Aliobaba

<<<<<<<<<<<<<<<<<<<<<<<<

Code: Alles auswählen

procedure TForm1.LoeschenClick(Sender: TObject);
Var
   x : string;
begin
 x :=DBEdit1.Text;
 with ZQuery1 do
  begin
   ZQuery1.Delete;    //   das geht auch!!
//     sql.Text := 'DELETE FROM `tabelle1` WHERE  Column1= :col1 ';
//     sql.Add(' LIMIT 1' );
//     ParamByName('Col1').AsString := x;
     ExecSQL;
   Close;
  end;
end;
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Antrepolit
Beiträge: 340
Registriert: Di 12. Sep 2006, 08:57
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: SQL-Statement für MySql anders als für SQLite?

Beitrag von Antrepolit »

@Aliobaba: Ich kann es nur nochmals postulieren: In einer konsitenten Datenbank hat LIMIT nichts in DELETE-Statements zu suchen. Gewöhn' dir das ab und lies dir mal die Theorie durch, wie man für Konsistenz sorgt. Stichwort: Primary Key.
Grüße, Antrepolit

care only if your os is really burning

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: SQL-Statement für MySql anders als für SQLite?

Beitrag von Aliobaba »

Hallo Antrepolit,

Deinen Hinweis in meinem letzten Thread habe ich auch noch sehr gut im Kopf - habe ihn auch nie angezweifelt!
Trotzdem möchte ich eben gerne das Programm kennenlernen und verschiedene Dinge ausprobieren. So falsch ist das ja sicher nicht.
Klar: Bei Eingabe eines Primary Keys sind alle Zweideutigkeiten ausgeräumt.

Danke!

Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6765
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: SQL-Statement für MySql anders als für SQLite?

Beitrag von af0815 »

Aliobaba hat geschrieben: Trotzdem möchte ich eben gerne das Programm kennenlernen und verschiedene Dinge ausprobieren. So falsch ist das ja sicher nicht.
Klar: Bei Eingabe eines Primary Keys sind alle Zweideutigkeiten ausgeräumt.
Wenn du lernen willst, dann würde ich es einmal mit den grundlegenden SQL Befehlen lernen und nicht mit Spezialitäten. Vor allen löst man dann Dinge mit den richtigen Mitteln. Wenn bei mir einer mit Limits in einem Update oder delete Statement kommt, so wird er von der Aufgabe abgezogen weil ich sehe das er von der Materie die Basics nicht Begriffen hat.

Ähnliches wenn ich 'Select * from table' in einem Projekt sehe. Das geht maximal bei einem Schulprojekt gut. Hat meiner Meinung nach nichts in einem Projekt zu suchen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: SQL-Statement für MySql anders als für SQLite?

Beitrag von Aliobaba »

af0815 hat geschrieben: Wenn du lernen willst, dann würde ich es einmal mit den grundlegenden SQL Befehlen lernen und nicht mit Spezialitäten.
... andererseits wird aber oft empfohlen, Parameter zu verwenden. Da ist man aber syntaxmäßig schon wieder weg von "grundlegenden SQL-Befehlen".
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6765
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: SQL-Statement für MySql anders als für SQLite?

Beitrag von af0815 »

Aliobaba hat geschrieben: ... andererseits wird aber oft empfohlen, Parameter zu verwenden. Da ist man aber syntaxmäßig schon wieder weg von "grundlegenden SQL-Befehlen".
Absolut nicht, das eine ist SQL selbst , das andere wie SQL am besten in die Umgebung eingebunden wird. Also zwei komplett getrennte Sachen.

Das was du hier ansprichst ist, wie setzte ich den String am besten zusammen, den ich dann dem SQL System übergebe. Und da haben Parameter den Vorteil das die Fehlerträchtigkeit sinkt, außerdem werden damit auch Fehler aus der Konfiguration von Sprachen oder anderen Einstellungen wie Zahlenformate minimiert.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten