Entwickler-Ecke

Sonstiges (Delphi) - Variable in SQL - Abfrage??


Lucky - Mi 06.12.06 09:46
Titel: Variable in SQL - Abfrage??
Morgen alle miteinander,
ich bräuchte mal wieder eure Hilfe, biiitttttteee:) Also mein Problem, ich hab ein Programm indem sich SQL-Abfragen immer wieder wiederholen und nun wollte ich diese in ein extra Unit, funktioniert auch, nun aber möchte ich in in meiner Abfrage Variablen verwenden um z.B. die Tabelle oder die Felder in dieser Abfrage ändern zu können


Delphi-Quelltext
1:
2:
form1.query1.SQL.Add('insert into "'+tabelle+'"("'+nrr+'", "'+name+'", "'+Feld+'")
values("'
+form1.Edit1.Text+'","'+form1.Edit2.Text+'","'+form1.Edit3.Text+'")');


und das Problem sind die Variablen ("'+nrr+'", "'+name+'", "'+Feld+'") da sagt er ungültiges Schlüsselwort Symbol-String:,

Was bedeutet dieser Fehler bzw. wie könnte ich diesen beheben? Bitte um Hilfe :flehan:

Moderiert von user profile iconjasocul: Delphi-Tags hinzugefügt


hansa - Mi 06.12.06 09:53

Was soll denn diese '''''''''' Orgie ? :shock: Gleich wird einer kommen, der wird noch "QuotedStr" empfehlen usw. Je nach Variablentyp brauchst du ParamByName. Z.B. so :


Delphi-Quelltext
1:
2:
3:
Dataset.Close;
DataSet.ParamByName ('NR').AsInteger := Edit1.Text;
Dataset.Open;


P.S.: nicht mal die Datenbank wurde genannt.


Lucky - Mi 06.12.06 10:05

Gibts da nicht vielleicht noch ne andere Möglichkeit?


Robert.Wachtel - Mi 06.12.06 10:26

user profile iconLucky hat folgendes geschrieben:
Gibts da nicht vielleicht noch ne andere Möglichkeit?

Warum? Was ist an einer parametrisierten Query auszusetzen?


hansa - Mi 06.12.06 10:37

user profile iconLucky hat folgendes geschrieben:
Gibts da nicht vielleicht noch ne andere Möglichkeit?


Kaum zu fassen. :shock: Eventuell gelingt es noch, aus den 3 Zeilen 2 zu machen. Angeblich braucht man das close nicht. Hier werden im Endeffekt aber wohl eher 300 Zeilen draus. Mehr kann ich nicht dazu sagen und sorry, meine Hexe ist bereits abgeflogen. :lol:

Edit : die Datenbank wurde trotz Hinweis darauf immer noch nicht genannt. Also, wenn die Frage völlig unwichtig ist, wie wohl hier, dann bitte das auch mal dazusagen.


Lucky - Mi 06.12.06 10:53

Ja mein Problem mit eurem Vorschlag ist das ich das net kann :cry: Ich werde es mir aber jetzt gleich mal zu Gemüte ziehen, achso hab ich vielleicht vergessen bin noch Anfänger :(
PS. SQL-Datenbank oder was wolltest du jetzt genau wissen?


ZeitGeist87 - Mi 06.12.06 12:10

Probiers mal so:



Delphi-Quelltext
1:
form1.query1.sql.text:= 'Insert into ' + tabelle + '(''' + nr + ''', ''' + name + ''', ''' + Feld + ''') values (''' + form1.edit1.text + ''', ''' + form1.edit2.text + ''', ''' + form1.edit3.text ''') ';                    


LG
Stefan


Lucky - Mi 06.12.06 13:59

@ZeitGeist ne funktioniert leider auch net sagt immer noch
Ungültiges Schlüsselwort
Symbol-String:,


jasocul - Mi 06.12.06 14:05

Liegt es vielleicht am Inhalt der Edit-Felder?


Lucky - Mi 06.12.06 14:11

sind eigentlich nur ganz normale StringWerte


jasocul - Mi 06.12.06 14:31

Und keiner dieser Werte enthält ein Komma?
Lass dir den Text des SQL-Statements doch mal mit einem ShowMessage anzeigen.


oldmax - Mi 06.12.06 14:37

Hi
Also, bevor dir hier die Finger brechen, Delphi hat etwas sehr nützliches, zumindest hab ich's, die UpDateSql-Objecte.
Damit ist es eigentlichsehr einfach, SQL-Strings nachzubilden.
Also, du besitzt eine Query, die an eine Tabelle gebunden ist. Schön. Nun nimmst du ein UpdateSQL-Object und ziehst es in deine Form, genau dorthin, wo deine Query halt ist. Der Query verpaßt du die Eigenschaft CachedUpdates = true und ganz unten im Objektinspektor findest du UpdateObject. Nun kannst du aus der Liste dein UpdateSQL auswählen. Anschließend probieren, ob Query auf Active geht.
Nun mit rechter Maustaste in das UpdateSQL klicken und den UpdateSQL-Editor aufrufen. Links das Indexfeld und rechts alle Felder markieren. Anschließend die SQL's erzeugen. Gibt es einen Button für. Fertig.
Beim Editieren darauf achten, das in der Query nur 1 Datensatz ist, also


Delphi-Quelltext
1:
MyQuery.SQL.Add('Select * from xyzTabelle where (Ident ='''+IntToStr( Id)+''')');                    


Datensatz editieren:

Delphi-Quelltext
1:
2:
3:
4:
5:
MyQuery.Edit;
  MyQuery['ersterText']:=Edit1.Text;
  MyQuery['ErsteInt']:=x;
 usw....
  UpdateSQl.Apply(UkModify); // hier wird das UpdateSQL- Object genommen. fertig


Datensatz enfügen


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
MyQuery.Insert;
  MyQuery['Ident']:=einneuer Ident; // nicht doppelt vergeben !!
  MyQuery['ersterText']:=Edit1.Text;
  MyQuery['ErsteInt']:=x;
 usw....
  UpdateSQl.Apply(UkInsert); // hier wird das UpdateSQL- Object genommen. fertig


Datensatz löschen
Auch hier erst wieder nur einen Datensatz holen über die
'Select .. Where Ident.. '

Dann einfach


Delphi-Quelltext
1:
UpdateSQl.Apply(UkDelete);                    


Ach ja, die ModifySQL, InsertSQL und DeleteSQL - Strings kannst du dir in dem SQL-Editor ansehen. Selbst komplizierte Abfragen bekommst du so hin.
Gruß oldmax


jaenicke - Mi 06.12.06 14:38

@user profile iconjasocul:Nein, im Source von user profile iconZeitGeist87 fehlt am Ende ein + ... ;-)
user profile iconZeitGeist87 hat folgendes geschrieben:


Delphi-Quelltext
1:
2:
3:
form1.query1.sql.text:= 'Insert into ' + tabelle + '(''' + nr + ''', ''' + name 
  + ''', ''' + Feld + ''') values (''' + form1.edit1.text + ''', ''' + form1.edit2.text 
  + ''', ''' + form1.edit3.text + ''') ';


raiguen - Mi 06.12.06 14:51

Moin :-)
@zeitgeist: die Hochkommaorgie hat ja hansa schon 'bemängelt'...

Was aber der entscheidene Fehler ist: in dem Beispiel werden die als Variable übergebenen Spaltennamen in ' ' eingeschlossen UND DAS DARF NICHT SEIN!! Da meckert der SQL-Parser(oder wie das Ding auch immer heissen mag) zurecht ;)

So müsste das SQL-Statement funktionieren:


Delphi-Quelltext
1:
2:
form1.query1.SQL.Add('INSERT INTO "'+tabelle+'"( '+ nrr + ', ' + name + ', ' + Feld + ' )
values("'
 + form1.Edit1.Text + '","' + form1.Edit2.Text + '","' + form1.Edit3.Text + '")');


jaenicke - Mi 06.12.06 15:01

Ähh, wie bitte? Seit wann gehen keine Hochkommata? Der Fehler kommt hier im übrigen vom Delphi-Compiler (den Grund hab ich ja eben auch geschrieben ;-)).
Aber sieh dir zum Bleistift mal die Beispiele bei Wikipedia an (ungefähr nach dem ersten Drittel), da sinds auch einzelne Anführungszeichen:
http://de.wikipedia.org/wiki/SQL
Meiner Menung nach gehen sowohl einfache als auch doppelte Anführungszeichen. Ich hab zwar bisher nicht viel mit SQL gemacht, aber soweit ich mich erinnere habe ich nur einfache Anführungszeichen benutzt.

// EDIT: Entschuldige, jetzt sehe ich erst, dass du bei den Spalten gar keine Anführungszeichen benutzt hast:
In Anführungszeichen ist doch aber auch bei Spaltennamen korrekt, das hab ich ebenfalls immer gemacht (naja, die paar Mal, die ich SQL bisher benutzt habe).

Dass die Vorgehensweise nicht sonderlich elegant ist, ist allerdings auch klar...


Lucky - Mi 06.12.06 15:11

Vielen Dank an alle für eure Hilfe!! :flehan:
@raigun so wie du es beschrieben hast funktioniert es jetzt auch, vielen vielen Dank noch mal!!! :flehan:


raiguen - Mi 06.12.06 15:13

Moin :-)
Bei Spaltennamen werden in der Regel KEINE Hochkommas (ob nun einzelne oder auch doppelte) gesetzt!
Und beim zitierten Wikipedia werden die Bespiele auch ohne Hochkommas geschrieben:
Zitat:

...
Beispiele:

INSERT INTO Adressen (Name, Vorname, Ort) VALUES ('Schroeder', 'Kurt', 'Köln')

Fügt eine Zeile mit den geg. Werten für die Spalten Name, Vorname und Ort in die Tabelle Adressen hinzu.

INSERT INTO Adressen (Name, Vorname, Ort) VALUES ('Schroeder', 'Kurt', 'Köln'), ('Schulz', 'Detlef', 'Oldenburg')

...


jaenicke - Mi 06.12.06 15:21

Ja, ich hatte zuerst nur gesehen, dass du doppelte statt einfache Anführungszeichen setzt :oops: , darauf bezog sich der Link zu Wikipedia...
Aber ich habs gerade ausprobiert: Ob ich bei Spaltennamen einfache oder doppelte Anführungszeichen setze ist total egal, es funktioniert mit beiden Arten und auch ohne ;-).


raiguen - Mi 06.12.06 15:47

user profile iconjaenicke hat folgendes geschrieben:
...
Aber ich habs gerade ausprobiert: Ob ich bei Spaltennamen einfache oder doppelte Anführungszeichen setze ist total egal, es funktioniert mit beiden Arten und auch ohne ;-).

Sicher?? Mit welcher DB? Hast du schlaubie evtl. den TabellenNamen vorangestellt (TabelleName.'FeldName') ...
DANN ist es auch wirklich egal, ob der SpaltenName in Hochkommas eingeschlossen ist oder auch nicht. ;)
Also bei LocalSQL (mit der allseits beliebten BDE) - und davon gehen ich mal aufgrund des EingangsThreads aus - funzt das nicht so ohne weiteres, wenn der Spaltennamen OHNE den vorangestellten qualifizierenden TabellenNAmen in Hochkommas gesetzt wird...
Oder hab ich da vllt was übersehen :gruebel:


jaenicke - Mi 06.12.06 16:00

Nein, ich benutze nicht díe BDE, wer tut das schon ;-)
Ich habe eine Open Source Lösung benutzt. Leider habe ich die nicht mehr im Netz gefunden, sonst würde ich hier den Link posten. Und Nein, ich hab nix davor geschrieben.


Delete - Mi 06.12.06 23:50

hallo miteinand, mal davon abgesehen, dass das problem schon gelöst ist, will ich auch noch meinen senf mit dazu geben ;-)

urspüngliche sql:

SQL-Anweisung
1:
2:
form1.query1.SQL.Add('insert into "'+tabelle+'"("'+nrr+'", "'+name+'", "'+Feld+'")
values("'
+form1.Edit1.Text+'","'+form1.Edit2.Text+'","'+form1.Edit3.Text+'")');


lässt sich doch vereinfachen zu:

neue SQL plus delphi
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
with form1.query1 do 
begin
 SQL.Add('insert into ? (?, ?, ?) values(?, ?, ?)'); // nur einmalig
 prepare;                                            // nur eimmalig
 params[0] := tabelle;                               // ab hier bei geänderten parametern
 params[1] := nrr;
 params[2] := name;
 parmas[3] := feld;
 params[4] := form1.edit1.text;
 params[5] := form1.edit2.text;
 parmas[6] := form1.edit3.text;
 execSQL; 
end;


jetzt mal ungetestet, müsst aber funktionieren... <HTH>


Blawen - Do 07.12.06 00:08

[quote="user profile iconGrenzgaenger"]

neue SQL plus delphi
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
with form1.query1 do 
begin
 SQL.Add('insert into ? (?, ?, ?) values(?, ?, ?)'); // nur einmalig
 prepare;                                            // nur eimmalig
 params[0] := tabelle;                               // ab hier bei geänderten parametern
 params[1] := nrr;
 params[2] := name;
 parmas[3] := feld;
 params[4] := form1.edit1.text;
 params[5] := form1.edit2.text;
 parmas[6] := form1.edit3.text;
 execSQL; 
end;


Pers. arbeite ich nicht mehr mit "Params" - einmal nachträglich einen neuen Parameter eingefügt und der Fehler ist vorprogrammiert. Wie wäre es mit dieser Variante:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
ZQ.SQL.Text := 'Insert Into TableName Set ' +
               'VORNAME   = :Vorname,  ' +
               'NACHNAME  = :Nachname, ' +
                ...
ZQ.ParamByName('Vorname').AsString  := Edit_Name.Text;
ZQ.ParamByName('Nachname').AsString := Edit_Nachname.Text;


hansa - Do 07.12.06 00:14

Siehe die allererste Antwort (von mir). 8) Danach kam die '''''-Orgie erst richtig in Fahrt. :lol: Grenzgaenger hat nur das SQL-insert im Klartext im Programm drin stehen. --> Gefahr für nächste '''''-Orgie. :shock: Das gehört nicht in die PAS sondern in die DFM. Siehe auch Beitrag von oldmax. Der schreibts IMHO aber komplizierter, als es ist. Am einfachsten geht es so : rechter Mausklick auf Dataset. SQL-Generator starten. Allgemeines Select-Statement eingeben. Z.B.: SELECT * FOM MEINETABLE Dann "Generate SQLs" auswählen. Insert, Update, Delete usw. werden automatisch erzeugt und zwar richtig ! Sind '"""'''"""" nötig, dann wird das automatisch auch gemacht. Oder eben nicht.


Robert.Wachtel - Do 07.12.06 00:27

user profile iconGrenzgaenger hat folgendes geschrieben:
[...] lässt sich doch vereinfachen zu:

neue SQL plus delphi
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
with form1.query1 do 
begin
 SQL.Add('insert into ? (?, ?, ?) values(?, ?, ?)'); // nur einmalig
 prepare;                                            // nur eimmalig
 params[0] := tabelle;                               // ab hier bei geänderten parametern
 params[1] := nrr;
 params[2] := name;
 parmas[3] := feld;
 params[4] := form1.edit1.text;
 params[5] := form1.edit2.text;
 parmas[6] := form1.edit3.text;
 execSQL; 
end;


jetzt mal ungetestet, müsst aber funktionieren... <HTH>

Nein, weder Tabellennamen noch Feldbezeichner können parametrisiert werden.


Delete - Do 07.12.06 00:27

@Blawen: du hast recht, mit "parambynames" kann man das alles schön vertauschen, aber lurk mal auf den einganstread von lucky, da wollte er alles variabel haben..., den tabellennamen, etc... und das lässt sich eben nur über generische parameter abdecken.. dabei muss er schon wissen was 'n string ist oder nicht... aber sonst geb ich dir schon recht.. die generischen parameter sind nicht so die pracht. auch halt ich gar nix von den parametern und bau mir lieber den sql string selbst zusammen... da weiss ich was ich hab ;-)

noch 'n schönen abend.


Delete - Do 07.12.06 00:29

user profile iconGrenzgaenger hat folgendes geschrieben:
@robert: bau mir lieber den sql string selbst zusammen... da weiss ich was ich hab ;-)


tja, siehe da... ;-)