Autor |
Beitrag |
pwsolaris
      
Beiträge: 71
Erhaltene Danke: 1
MS DOS, Win 95, Win 98, Win ME, Win XP, Win Vista, Win 7 Ultimate
Delphi 5 Enterp., Delphi 2007, Delphi 2009, Informix 4GL, VB .NET, MS/SQL, PL/SQL
|
Verfasst: Di 03.08.10 21:28
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
Moderiert von Narses: SQL-Tags hinzugefügt
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: 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 
      
Beiträge: 71
Erhaltene Danke: 1
MS DOS, Win 95, Win 98, Win ME, Win XP, Win Vista, Win 7 Ultimate
Delphi 5 Enterp., Delphi 2007, Delphi 2009, Informix 4GL, VB .NET, MS/SQL, PL/SQL
|
Verfasst: 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:
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.
Zuletzt bearbeitet von pwsolaris am Mi 04.08.10 09:29, insgesamt 1-mal bearbeitet
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Mi 04.08.10 09:24
pwsolaris hat folgendes geschrieben : | Delphi-Quelltext 1:
| SQL.Add('UPDATE TABLE tabelle_charakter'); | |
1. Da würde ich das Wort "TABLE" weglassen.
2. Die Namen Int, Name und Level sind meines Wissens reservierte Wörter. Du solltest den Tabellenspalten andere Namen geben.
Siehe z. B.: support.microsoft.co...p&NoWebContent=1
Zuletzt bearbeitet von Gerd Kayser am Mi 04.08.10 09:38, insgesamt 2-mal bearbeitet
|
|
pwsolaris 
      
Beiträge: 71
Erhaltene Danke: 1
MS DOS, Win 95, Win 98, Win ME, Win XP, Win Vista, Win 7 Ultimate
Delphi 5 Enterp., Delphi 2007, Delphi 2009, Informix 4GL, VB .NET, MS/SQL, PL/SQL
|
Verfasst: 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
      
Beiträge: 39
Erhaltene Danke: 2
|
Verfasst: 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
      
Beiträge: 992
Erhaltene Danke: 1
WIN 7
D7 Prof., C#, RAD XE Prof.
|
Verfasst: 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.
_________________ Gruß Smiegel
Ich weiß, daß ich nichts weiß, aber ich weiß mehr als die, die nicht wissen, daß sie nichts wissen. (Sokrates)
|
|
pwsolaris 
      
Beiträge: 71
Erhaltene Danke: 1
MS DOS, Win 95, Win 98, Win ME, Win XP, Win Vista, Win 7 Ultimate
Delphi 5 Enterp., Delphi 2007, Delphi 2009, Informix 4GL, VB .NET, MS/SQL, PL/SQL
|
Verfasst: 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 
|
|
Muck
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: 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 
      
Beiträge: 71
Erhaltene Danke: 1
MS DOS, Win 95, Win 98, Win ME, Win XP, Win Vista, Win 7 Ultimate
Delphi 5 Enterp., Delphi 2007, Delphi 2009, Informix 4GL, VB .NET, MS/SQL, PL/SQL
|
Verfasst: 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
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: 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 
      
Beiträge: 71
Erhaltene Danke: 1
MS DOS, Win 95, Win 98, Win ME, Win XP, Win Vista, Win 7 Ultimate
Delphi 5 Enterp., Delphi 2007, Delphi 2009, Informix 4GL, VB .NET, MS/SQL, PL/SQL
|
Verfasst: 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
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: 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 
      
Beiträge: 71
Erhaltene Danke: 1
MS DOS, Win 95, Win 98, Win ME, Win XP, Win Vista, Win 7 Ultimate
Delphi 5 Enterp., Delphi 2007, Delphi 2009, Informix 4GL, VB .NET, MS/SQL, PL/SQL
|
Verfasst: 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
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: 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
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: 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 
      
Beiträge: 71
Erhaltene Danke: 1
MS DOS, Win 95, Win 98, Win ME, Win XP, Win Vista, Win 7 Ultimate
Delphi 5 Enterp., Delphi 2007, Delphi 2009, Informix 4GL, VB .NET, MS/SQL, PL/SQL
|
Verfasst: 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
      
Beiträge: 39
Erhaltene Danke: 2
|
Verfasst: 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 
      
Beiträge: 71
Erhaltene Danke: 1
MS DOS, Win 95, Win 98, Win ME, Win XP, Win Vista, Win 7 Ultimate
Delphi 5 Enterp., Delphi 2007, Delphi 2009, Informix 4GL, VB .NET, MS/SQL, PL/SQL
|
Verfasst: 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  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
      
Beiträge: 16
D6
|
Verfasst: Mo 16.08.10 02:19
|
|
|