Entwickler-Ecke
Datenbanken - Syntaxfehler in UPDATE-Anweisung
pwsolaris - Di 03.08.10 21:28
Titel: Syntaxfehler in UPDATE-Anweisung
Hallo liebe Community,
da ihr mir bei meinem letzten Problem so schnell geholfen habt, woltle ich mich wieder an euch wenden.
Dieses mal ist es mir aber etwas peinlich, da ich echt schon ne Menge erfahrung mit SQL & Co. habe.
Also ich habe folgende Query:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| with ADO_update do begin SQL.Clear; SQL.Add('UPDATE tabelle_charakter'); SQL.Add(' SET Klasse = ' + IntToStr(Klasse)); SQL.Add(', Geschlecht = "' + charakter_geschlecht + '"'); SQL.Add(', MaxHP = ' + IntToStr(pb_char_hp.Max)); SQL.Add(', Level = ' + lb_charlevelwert.Caption); SQL.Add(', Erfahrung = ' + lb_charerfahrungwert.Caption); SQL.Add(', Str = ' + lb_charstrwert.Caption); SQL.Add(', Agi = ' + lb_charagiwert.Caption); SQL.Add(', Vit = ' + lb_charvitwert.Caption);
SQL.Add(', Int = ' + lb_charintwert.Caption); SQL.Add(', Statuspunkte = ' + lb_charstatuspunktewert.Caption); SQL.Add(', Waffe = ' + IntToStr(waffe)); SQL.Add(', Rüstung = ' + IntToStr(rüstung)); SQL.Add(' WHERE Name = "' + lb_charnamewert.Caption + '"'); ExecSQL; end; |
Als Ergebnis erhalte ich dann sowas:
SQL-Anweisung
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| UPDATE tabelle_charakter SET Klasse = 1 , Geschlecht = "M" , MaxHP = 50 , HP = 50 , Level = 1 , Erfahrung = 0 , Str = 5 , Agi = 5 , Vit = 5 , Int = 5 , Statuspunkte = 0 , Waffe = 2 , Rüstung = 3 WHERE Name = "Test" |
Vor dem WHERE steht ein Leerzeichen. Das wird hier wohl nur abgeschnitten.
Die Felder Klasse, Waffe und Rüstung sind vom Typ Integer als Verweis auf eine Haupttabelle.
Wahrscheinlich sehe ich gerade den Wald vor lauter Bäumen nicht aber wo is da im UPDATE der fehler?
ich hoffe Ihr könnt mir da mal helfen :D
Moderiert von
Narses: SQL-Tags hinzugefügt
Gerd Kayser - Mi 04.08.10 04:52
pwsolaris hat folgendes geschrieben : |
Wahrscheinlich sehe ich gerade den Wald vor lauter Bäumen nicht aber wo is da im UPDATE der fehler? |
Verwendest Du vielleicht reservierte Wörter? Int, Name und Level sind dafür heiße Kandidaten.
Steht der Name auch als "Test" in der Datentabelle drinnen oder als "TEST " (mit Großbuchstaben und / oder zusätzlichen Leerzeichen)?
Außerdem würde ich das auf ParamByName umstellen und einen bündigen rechten Rand verwenden. Der Source ist ja praktisch unlesbar, und Leerzeichen kosten nix. :)
Beispiel mit IBQuery (bei ADO sollte das ähnlich sein, evtl. die Syntax mal nachschlagen):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| with DatenModul.IBQuery1 do begin SQL.Clear; SQL.Add('UPDATE TabVerfahrensnamen '); SQL.Add('SET '); SQL.Add(' Verfahren = :NeuVerfahren '); SQL.Add('WHERE '); SQL.Add(' (Verfahren = :AltVerfahren) '); ParamByname('AltVerfahren').AsString := Verfahren1; ParamByname('NeuVerfahren').AsString := Verfahren2; ExecSQL; end; |
pwsolaris - Mi 04.08.10 06:36
Also erst einmal danke für die frühe Hilfe :)
Habe das nun erst einmal so geändert, dass ich Parameter benutze:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| with ADO_update do begin SQL.Clear; SQL.Add('UPDATE tabelle_charakter'); SQL.Add(' SET Klasse = :Klasse'); SQL.Add(', Geschlecht = :Geschlecht'); SQL.Add(', MaxHP = :MaxHP'); SQL.Add(', Level = :Level'); SQL.Add(', Erfahrung = :Erfahrung'); SQL.Add(', Str = :Str'); SQL.Add(', Agi = :Agi'); SQL.Add(', Vit = :Vit'); SQL.Add(', Int = :Int'); SQL.Add(', Statuspunkte = :Statuspunkte'); SQL.Add(', Waffe = :Waffe'); SQL.Add(', Rüstung = :Rüstung'); SQL.Add(' WHERE Name = :Name'); Parameters.ParamByName('Klasse').Value := Klasse; Parameters.ParamByName('Geschlecht').Value := '"' + charakter_geschlecht + '"'; Parameters.ParamByName('MaxHP').Value := pb_char_hp.Max; Parameters.ParamByName('Level').Value := lb_charlevelwert.Caption; Parameters.ParamByName('Erfahrung').Value := lb_charerfahrungwert.Caption; Parameters.ParamByName('Str').Value := lb_charstrwert.Caption; Parameters.ParamByName('Agi').Value := lb_charagiwert.Caption; Parameters.ParamByName('Vit').Value := lb_charvitwert.Caption; Parameters.ParamByName('Int').Value := lb_charintwert.Caption; Parameters.ParamByName('Statuspunkte').Value := lb_charstatuspunktewert.Caption; Parameters.ParamByName('Waffe').Value := waffe; Parameters.ParamByName('Rüstung').Value := rüstung; Parameters.ParamByName('Name').Value := '"' + lb_charnamewert.Caption + '"'; ExecSQL; end; |
Jetzt bekomme ich jedoch immer die Meldung, das der Parameter "Klasse" nicht gefunden werden kann und die anderen dann wahrscheinlich auch nicht. Ich habe den Parameter schon über den Objektinspector angelegt, aber das half auch nicht.
Im Quellcode habe ich noch ein weiteres SQL Query, mit dem ich Daten aus einer Tabelle lösche. Da hat auch alles ohne Parameter funktioniert.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| with ADO_Query do begin SQL.Clear; SQL.Add('DELETE FROM tabelle_charakter '); SQL.Add('WHERE Name = "' + lb_namewert.Caption + '"'); ExecSQL; end; |
Ist zwar jetzt nicht so umfangreich aber es ist im Prinzip ja das gleiche. Einen Wert aus einer Variablen an mein Query hängen.
Noch irgendeine Idee, was ich da nun falsch mache?
EDIT:
Der Fehler, dass der Parameter "Klasse" nicht gefunden werden kann ist nun weg. Jetzt kommt wieder "Syntaxfehler in der UPDATE-Anweisung".
Langsam bin ich ratlos :(
EDIT: In der Zeile "UPDATE tabelle_charakter" habe ich das Wort "TABLE" entfernt. War jedoch nicht die Fehlerquelle.
pwsolaris - Mi 04.08.10 09:28
Oh :)
Das ist noch ein Überbleibsel meiner morgigen Test-Versuche.
Wie im ersten Post zu sehen, steht es dort ja nicht.
Leider ist das aber nicht die Quelle meines Syntaxfehlers :(
Tintenblut - Mi 04.08.10 10:46
Moin moin!
So spontan würde ich darauf tippen, dass dein Problem hier liegt:
Delphi-Quelltext
1:
| SQL.Add(', Geschlecht = "' + charakter_geschlecht + '"'); |
Delphi-Quelltext
1:
| SQL.Add(' WHERE Name = "' + lb_charnamewert.Caption + '"'); |
Du verwendest Anführungszeichen wo im normalen SQL Hochkommatas ' stehen würden, richtig?
Versuchs dann mal so:
Delphi-Quelltext
1:
| SQL.Add(', Geschlecht = ' + QuotedStr(charakter_geschlecht)); |
Delphi-Quelltext
1:
| SQL.Add(' WHERE Name = ' + QuotedStr(lb_charnamewert.Caption)); |
Edit:// Aber ich glaube dann würde das kein Syntax-Fehler, sondern als ungültiger Bezeichner beim Ausführen angemerkt werden.
Ein Versuch ists aber mal wert
Gruß
smiegel - Mi 04.08.10 11:19
Hallo,
wenn man Parameter benutzt, werden bei Strings keine Anführungszeichen angegeben - ausser Sie gehören zum Text der in der DB gespeichert werden soll. Ist dies der Fall, dann muss man sie ausmaskieren. Bei Access muss man die Anführungszeichen verdoppeln.
Bei Insert, Update und Delete würde ich die Komponente TADOCommand statt TADOQuery nehmen.
pwsolaris - Mi 04.08.10 11:33
Schon einmal Danke für die Tipps. Ich werde mich heute Abend direkt an die Umsetzung machen und finde hoffentlich eine Lösung für mein Problem.
Am liebsten würde ich das jetzt schon testen :D
Muck - Mi 04.08.10 17:34
Hallo,
ADO unterstuetzt reservierte Woerter als Feldnamen mit folgender Schreibweise:
User ist ein reserviertes Wort:
Delphi-Quelltext
1:
| SQL.Add('update x set x."user"='+QuotedStr(Y)); |
Bei Benutzung dieser Schreibweise immer die Delphi Function QuotedStr benutzen, da diese das Zeichen ' innerhalb des Strings richtig behandelt. In Deinem Beispiel wirst Du einen Fehler erhalten, falls der String ein chr(39) enthaelt.
cu
Markus
pwsolaris - Mi 04.08.10 20:18
Also die reservierten Spaltennamen habe ich nun einmal umbenannt und getestet. Gleicher Fehler.
Dann habe ich es mit Mucks Methode versucht und dies ist ebenfalls gescheitert.
Es bleibt bei einem Syntaxfehler in der UPDATE-Anweisung.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| with ADO_update do begin SQL.Clear; SQL.Add('UPDATE TABLE tabelle_charakter'); SQL.Add(' SET "Klasse" = ' + QuotedStr(IntToStr(klasse))); SQL.Add(', "Level" = ' + QuotedStr( lb_charlevelwert.Caption)); SQL.Add(', "Int" = ' + QuotedStr(lb_charintwert.Caption)); SQL.Add(' WHERE "Name" = ' + QuotedStr(charakter_name)); ExecSQL; end; |
So sieht das nun ungefähr aus. Muss ich jeden Spaltennamen in dieser Form schreiben:
tabelle_charakter."Klasse"
oder reicht es so, wie ich es gemacht habe?
EDIT: Muss ich dann QuotedStr auch benutzen, wenn ich Integer-Werte in die Tabelle speichern möchte?
Muck - Mi 04.08.10 20:50
Hallo,
getestet mit ADO und SQL Express 2005. Funktioniert.
Delphi-Quelltext
1: 2:
| sql.add('create table tabelle_charakter("int" int,"Level" int,Klasse varchar(8))'); sql.add('update tabelle_charakter set "Level"=4,"Int"=1,Klasse='+QuotedStr('Test')); |
In Deinem Beispiel:
Ersetze update table tabelle_.... mit update tabelle_...
QuotedStr ist nur noetig wenn strings oder date in dieser Schreibweise angesprochen werden.
cu
Markus
pwsolaris - Mi 04.08.10 21:02
Das UPDATE TABLE war ja imemrnoch drinne...
Nun is der Syntaxfehler schonmal weg und ich habe wieder den Fehler das dem Wert 'Klasse' kein Standardparameter zugewiesen wird...
Bei dem Fehler springt er aber nur zu den Spaltennamen, die ich in ' " ' geschrieben habe...
Also
"Klasse"
"Int"
usw...
entferne ich nun zum Testen die Anführungszeichen, bekomme ich wieder den Syntaxfehler
EDIT:
Ich habe nun mal weiter rumgespielt und folgende Zeilen verändert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| with ADO_update do begin SQL.Clear; SQL.Add('UPDATE tabelle_charakter'); SQL.Add(' SET "Klasse" = :Klasse'); ... SQL.Add(' WHERE "Name" = ' + QuotedStr(lb_charnamewert.Caption)); Parameters.ParamByName('Klasse').Value := klasse; ExecSQL; end; |
Die Meldung ist nun, dass für mindestens einen wirklichen Parameter kein Wert angegeben ist... aber den habe ich doch zugewiesen...
Muck - Mi 04.08.10 21:30
Hallo,
teste doch mal folgendes:
Benutze die alte Schreibweise ohne Nutzung von Params. Teile ADO das mit durch setzen von ParamCheck.
Delphi-Quelltext
1: 2: 3: 4:
| ADO_Update.ParamCheck:=false; ADO_update.sql.clear; ADO_Update.sql.add('UPDATE tabelle_charakter SET "Klasse"='+IntToStr(Klasse)+' WHERE "Name"='+QuotedStr(lb_charnamewert.Caption)); ADO_Update.ExecSQL; |
cu
Markus
Edit:Klasse ist ein Integer daher IntToStr statt QuotedStr
pwsolaris - Mi 04.08.10 21:35
So...
Habe nun im Objektinspektor für die Komponente ADO_update die Eigenschaft "ParamCheck" auf True gesetzt (War vorher schon habe aber auf False und zurück auf True gesetzt).
Mein Code sieht jetzt so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| with ADO_update do begin SQL.Clear; SQL.Add('UPDATE tabelle_charakter'); SQL.Add(' SET "Klasse" = ' + IntToStr(klasse)); SQL.Add(', Geschlecht = ' + QuotedStr(charakter_geschlecht)); SQL.Add(', MaxHP = ' + IntToStr(pb_char_hp.Max)); SQL.Add(', "Level" = ' + lb_charlevelwert.Caption); SQL.Add(', Erfahrung = ' + lb_charerfahrungwert.Caption); SQL.Add(', Str = ' + lb_charstrwert.Caption); SQL.Add(', Agi = ' + lb_charagiwert.Caption); SQL.Add(', Vit = ' + lb_charvitwert.Caption); SQL.Add(', "Int" = ' + lb_charintwert.Caption); SQL.Add(', Statuspunkte = ' + lb_charstatuspunktewert.Caption); SQL.Add(', Waffe = ' + IntToStr(waffe)); SQL.Add(', Rüstung = ' + IntToStr(rüstung)); SQL.Add(' WHERE "Name" = ' + QuotedStr(lb_charnamewert.Caption)); ExecSQL; end; |
Beim ausführen bekomme ich nun folgenden Fehler (OLE Exception):
Parameter"Klasse" hat keinen Standardwert
Muck - Mi 04.08.10 21:55
Hi,
also wenn Du keine Params benutzt, solltest Du ParamCheck immer auf false setzen.
Was wenn in Deinem Beispiel jemand als Character Name ':Hunter'
benutzt. ADO wird das als Parameter erkennen und einen Fehler auswerfen.
Zu dem Fehler, checke die Tabellendefinition. Das Feld Klasse ist wahrscheinlich als String definiert wuerde ich mal tippen.
Bei mir funktioniert Deine Anweisung fehlerlos.
bis denne
Markus
Gerd Kayser - Mi 04.08.10 22:43
Muck hat folgendes geschrieben : |
Zu dem Fehler, checke die Tabellendefinition. Das Feld Klasse ist wahrscheinlich als String definiert wuerde ich mal tippen. |
Die meisten Felder dürften wohl vom Typ Integer sein, denen er aber Strings zuweist, statt das vorher mit StrToInt umzuwandeln.
pwsolaris - Do 05.08.10 06:24
Guten Morgen,
Also ich konnte nun die fehlerhaften Spalten eingrenzen und kann sagen, dass es an den Spalten Level und Int liegt.
Versucht habe ich heute schon folgendes für diese beiden Spalten:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| with ADO_update do begin SQL.Clear; SQL.Add('UPDATE tabelle_charakter'); SQL.Add(' SET Klasse = ' + IntToStr(klasse)); SQL.Add(', "Level" = ' + lb_charlevelwert.Caption); SQL.Add(' WHERE Name = ' + QuotedStr(lb_charnamewert.Caption)); ExecSQL; end; |
Nun bleibt nur noch die Meldung, dass für min. einen erforderlichen Parameter kein Wert angegeben wurde.
Für ADO_update steht die Eigentschaft "ParamCheck" weiterhin auf "False"
Wenn ich das Ganze dann wie folgt erweitere:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| with ADO_update do begin SQL.Clear; SQL.Add('UPDATE tabelle_charakter'); SQL.Add(' SET Klasse = ' + IntToStr(klasse)); SQL.Add(', "Level" = :xLevel'); SQL.Add(' WHERE Name = ' + QuotedStr(lb_charnamewert.Caption)); Parameters.ParamByName('xLevel').Value := StrToInt(lb_charlevelwert.Caption); ExecSQL; end; |
Bleibt der Fehler weiterhin bestehen.
Tintenblut - Do 05.08.10 10:02
Delphi-Quelltext
1:
| Parameters.ParamByName('xLevel').Value := StrToInt(lb_charlevelwert.Caption); |
Warum machst du die Zuweisung erst nachdem du den Parameter in der SQL-Anweisung verwendet hast?
pwsolaris - Do 05.08.10 16:17
Also ich habe bisher noch die diese Parameter benutzen müssen und habe mich da an dem Post von Gerd Kayser orientiert.
Bevor ich nun wieder die Spalten umbenenne werde ich mal die Parameterzuweisung direkt unter das SQL.Clear; setzen
EDIT:
Habe nun mal die Parameter (ParamByName) direkt hinter das SQL.Clear; gesetzt und dann kam der Fehler, das der Parameter nicht gefunden wurde.
Meine letzte Option ist nun, die beiden Tabellenspalten umzubenennen. Wenn das nicht klappt kehre ich der Access Datenbank den Rücken zu :D Von wegen "Hey das benutz ich, ist bestimmt einfach, weils ja Access ist"...
EDIT 2:
So Spaltennamen umbenennen hat letzendlich funktioniert. Wollte ich zwar eigentlich nicht machen, da mir nun die Tabelle irgendwie "unsauber" vorkommt aber egal :)
Danke für eure Hilfe
Theophilus - Mo 16.08.10 02:19
Zitat: |
...
Wenn das nicht klappt kehre ich der Access Datenbank den Rücken zu :D Von wegen "Hey das benutz ich, ist bestimmt einfach, weils ja Access ist"...
EDIT 2:
So Spaltennamen umbenennen hat letzendlich funktioniert. Wollte ich zwar eigentlich nicht machen, da mir nun die Tabelle irgendwie "unsauber" vorkommt aber egal :)
|
"INT" und "LEVEL" sind in SQL reservierte Wörter, das hat überhaupt nichts mit Access zu tun! Solche Wörter haben als Spaltennamen nichts verloren. Man könnte Access höchstens den Vorwurf machen, dass es diese Bezeichner bei einer Tabellendefinition überhaupt akzeptiert. Allerdings sollte es möglich sein, andere Bezeichner zu finden, ohne dass die Tabelle "unsauber" aussieht...
;)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!