Entwickler-Ecke

Datenbanken - Query-Anführungszeichen?


D. Annies - Do 02.07.09 20:49
Titel: Query-Anführungszeichen?
Hi, Delpher,

nochmal ganz herzlichen Dank für eure Hilfe bei meinem letzten Thread!

Ich muss also anders vorgehen (schade).

Jetzt geht es um folgende (fehlerhafte) Query:


Delphi-Quelltext
1:
2:
3:
4:
5:
  query1.Close;
    query1.SQL.Text :=
      format('select max(punkte) as maxpkt from "%s" S ' +
             'where (geschlecht = ''w'') and (klasse like "%s" ) ', [Table2.tablename, '''%'+listbox1.items[n]+'''%']);
  query1.Open;


Es geht vieleicht nur um die Anzahl der Anführungszeichen. (?)
Die Fehlermeldung ist: '' ist kein gültiger Integerwert.

Die Klausel [Table2.tablename, '%7%'] funktioniert übrigens!

Habt ihr eine Idee?

Danke, Detlef


jaenicke - Do 02.07.09 21:13

Sind die Anführungszeichen nicht zu viel? :gruebel:
user profile iconD. Annies hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
    query1.SQL.Text :=
      format('select max(punkte) as maxpkt from "%s" S ' +
             'where (geschlecht = ''w'') and (klasse like "%s" ) ', [Table2.tablename, '''%'+listbox1.items[n]+'''%']);
Bzw. wenn dann nicht symmetrisch gesetzt.


Niko S. - Do 02.07.09 21:13


Delphi-Quelltext
1:
'''%'+listbox1.items[n]+'%'''])                    

So rum wäre das % schonmal besser.
Aber listbox1.items[n] liefert doch soweit ich weiß keinen integerwert zurück?

//edit
zu lahm :x


D. Annies - Do 02.07.09 21:26

Danke, ihr zwei, ich hab's jetzt gesehen.

By the way: Nachdem der Weg von gestern nicht ging, habe ich jetzt den folgenden Weg genommen, und der geht:


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:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
n := 2; k := 2;
  repeat
    query1.Close;
      query1.SQL.Text :=
        format('select max(punkte) as maxpkt from "%s" S ' +
               'where (geschlecht = ''w'') and (klasse like "%s" ) ', [Table2.tablename, ''+listbox1.items[k]+'%']);
    query1.Open;
    showmessage('Mädchen: '+listbox1.Items[k]+ inttostr(query1.RecordCount));

    query1.First;
    stringgrid1.Cells[0,n] := inttostr(n);
    stringgrid1.Cells[1,n] := query1.fieldbyname('maxPkt').asstring;

    table2.locate('punkte', Query1.fieldbyname('maxpkt').asstring, []);

    stringgrid1.Cells[2,n] := table2.fieldbyname('Geschlecht').asstring;
    stringgrid1.Cells[3,n] := table2.fieldbyname('Klasse').asstring;
    stringgrid1.Cells[4,n] := table2.fieldbyname('Name').asstring;
    stringgrid1.Cells[5,n] := table2.fieldbyname('Vorname').asstring;
    inc(n);

    query1.Close;
      query1.SQL.Text :=                                                                // '7%' geht
        format('select max(punkte) as maxpkt from "%s" S ' +
               'where (geschlecht = ''m'') and (klasse like "%s") ', [Table2.tablename, ''+listbox1.items[k]+'%']);
    query1.Open;
    showmessage('Jungen: '+listbox1.Items[k]+inttostr(query1.RecordCount));

    query1.First;
    stringgrid1.Cells[0,n] := inttostr(n);
    stringgrid1.Cells[1,n] := query1.fieldbyname('maxPkt').asstring;

    table2.locate('punkte', Query1.fieldbyname('maxpkt').asstring, []);

    stringgrid1.Cells[2,n] := table2.fieldbyname('Geschlecht').asstring;
    stringgrid1.Cells[3,n] := table2.fieldbyname('Klasse').asstring;
    stringgrid1.Cells[4,n] := table2.fieldbyname('Name').asstring;
    stringgrid1.Cells[5,n] := table2.fieldbyname('Vorname').asstring;
    inc(n);
    inc(k);  //!!!
  until k = listbox1.Items.Count;

  stringgrid1.RowCount := n;


Mag "umständlich" erscheinen, aber verständlich, und funzt!!

Gruß, Detlef (der tapfere :D )


jaenicke - Do 02.07.09 21:32

user profile iconD. Annies hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
format('select max(punkte) as maxpkt from "%s" S ' +
  'where (geschlecht = ''w'') and (klasse like "%s" ) ', [Table2.tablename, ''+listbox1.items[k]+'%']);
Das kannst du dir auch sparen, das bewirkt rein gar nichts. ;-)


D. Annies - Do 02.07.09 22:15

UPS, danke, Sebastian. [Hast mal wieder genau hingeguckt, aber alles andere bringt sowieso nichts...]

P.S. Die obige Lösung hat noch den "Nachteil", dass die gefundene Person zwar die Punktzahl hat, aber nicht aus der (richtigen) Klasse stammt. :evil:

Detlef


jfheins - Do 02.07.09 22:26

user profile iconD. Annies hat folgendes geschrieben Zum zitierten Posting springen:
P.S. Die obige Lösung hat noch den "Nachteil", dass die gefundene Person zwar die Punktzahl hat, aber nicht aus der (richtigen) Klasse stammt. :evil:

Liegt evtl. am like - das lässt ja mehrere klassen zu - geht's vll. wenn du das durch eine Gleichheitsbedingung ersetzt?


jaenicke - Do 02.07.09 22:31

Also ich habe mit MySQL nicht so viel gemacht bisher, aber ginge es nicht einfach so?

Delphi-Quelltext
1:
2:
Format('select max(punkte) as maxpkt from "%s" ' +
  'where geschlecht = "w" and klasse like "%s";', [Table2.TableName, ListBox1.Items[k] + '%']);


D. Annies - Do 02.07.09 22:43

Also, ich meinte: der Query-Befehl ist so schon ok, aber es kann sein, dass die mit LOCATE gefundene Klasse nicht die richtige ist, wenn nämlich 2 Personen (gleichen Geschlechts) auch genau die gleiche Punktzahl haben.

Detlef


jfheins - Do 02.07.09 22:48

Könntest du nicht 2 Queries verwenden?

also eine:

SELECT max( punkte ), geschlecht, klasse
FROM pupils
GROUP BY klasse, geschlecht

damit solltest du zu jeder klasse und jedem geschlecht die beste Punktzahl heruasfinden. Und dann für jede Ergebnszeile sowas:

select * from pupils where punkte=query1.punkte and geschlecht=query1.geschlecht and klasse=query1.klasse

falls du da mehrere rausbekommst, sind die beiden gleich gut - gibt also keinen Besten :P


D. Annies - Do 02.07.09 22:51

Danke dir, probiere ich aber erst morgen aus und melde mich dann wieder. Muss jetzt in die Heia!

Detlef


mkinzler - Fr 03.07.09 07:31

Wie schon öfters bemerkt, solltest du dir wirklich mal die Verwendung von (SQL-)Parametern anschauen.


Delete - Fr 03.07.09 12:33

Und sollte das aus irgendwelchen Gründen nicht möglich sein, zumindest QuotedStr verwenden.


D. Annies - Sa 04.07.09 10:06

Danke!
Ich werde mir mal Beispiele mit quotedstr ansehen.

Gruß, Detlef


pto1 - So 05.07.09 10:32

probier mal die Schreibweisen

query1.SQL.Text := format(
'select max(punkte) as maxpkt from %s where (geschlecht = ''w'') and (klasse like ''%%%s%%'' ) ',
[Table2.tablename, listbox1.items[n]]);

oder mit Parametern
query1.SQL.Text := format(
'select max(punkte) as maxpkt from %s where (geschlecht = ''w'') and (klasse like :klasse ) ',
[Table2.tablename]);
query.params[0].asString:= '%'+ listbox1.items[n]+ '%';

Der Alias S für die Tabelle ist überflüssig, wird ja nirgendwo in der Query verwendet.


Delete - So 05.07.09 11:03


Delphi-Quelltext
1:
2:
query1.SQL.Text :=  format('select max(punkte) as maxpkt from %s where (geschlecht = %s) and (klasse like %s)'
  [Table2.tablename, QuotedStr('w'),QuotedStr(listbox1.items[n] + '%')]);


D. Annies - Di 07.07.09 20:18

Vielen Dank für die "Nachsorge",
Detlef


delphijanka - Mi 05.08.09 15:11

Problem:

Text: String;
...
Text := 'SELECT x FROM y WHERE x = "xy" ';

Wenn x eine String-Spalte in der DB ist (zb VARCHAR), welche ""-zeichen soll ich nutzen?

Danke.


Delete - Mi 05.08.09 15:22

Am besten gar keine, sondern wie bereits erwähnt SQL-Parameter. Oder wie auch erwähnt QuotedStr verwenden, das sollte passen.


delphijanka - Do 06.08.09 15:49

Habe gerade etwas recherchiert und doch auf die Lösung gekommen, die aber imo beschäment ist (fu Delphi)

var
str: String;
sql: String;

str := 'blabla';

sql := 'SELECT * FROM Tabelle WHERE Attribut = ' + '''' + str + '''';

(also ' - Zeichen 4 mal auf jeder Seite)


FaTaLGuiLLoTiNe - Do 06.08.09 15:52

user profile icondelphijanka hat folgendes geschrieben Zum zitierten Posting springen:


Delphi-Quelltext
1:
sql := 'SELECT * FROM Tabelle WHERE Attribut = ' + '''' + str + '''';                    


Geht auch kürzer:


Delphi-Quelltext
1:
sql := 'SELECT * FROM Tabelle WHERE Attribut = ''' + str + '''';                    


Allerdings sollte man sich ruhig den Einwand zu Herzen nehmen, Parameter zu verwenden.


Tilman - Do 06.08.09 15:56

oder so

Delphi-Quelltext
1:
  sql := 'SELECT * FROM Tabelle WHERE Attribut = ' +#39+ str + #39;                    


DonManfred - Do 06.08.09 17:14


Delphi-Quelltext
1:
sql := 'SELECT * FROM Tabelle WHERE Attribut = '+QuotedStr(str);                    


Tilman - Do 06.08.09 17:20

die Möglichkeit wurde schon mehrmals genannt in diesem Thread. Ich glaube es wurde schon alles gesagt, nur noch nicht von jedem 8)

(c) by Karl Valentin


DonManfred - Do 06.08.09 17:23

user profile iconTilman hat folgendes geschrieben Zum zitierten Posting springen:
die Möglichkeit wurde schon mehrmals genannt in diesem Thread. Ich glaube es wurde schon alles gesagt, nur noch nicht von jedem 8)


Vielleicht hat es der Threadstarter nur noch nicht realisiert, das man es SO machen kann!? Gesagt wurde es mehrfach, ja; er ist aber bei keinem drauf eingegangen.


alzaimar - Do 06.08.09 18:42

Ich habe einen Geheimtipp: "Parameter". :shock:
Und noch einen: "QuotedStr". :flehan:

Aber eins wurde noch nie nicht vorgeschlagen: Temporäre Variablen, um so komplexe Konstrukte wie '%Foobar%' (sogar mit! Anführungszeichen) zu generieren, zwischenzuspeichern und zu verifizieren. :dance2:


Tilman - Do 06.08.09 18:43

jemand der Alzheimer heißt darf das. :P


jfheins - Do 06.08.09 23:27


Delphi-Quelltext
1:
sql := 'SELECT * FROM Tabelle WHERE Attribut = "' + str + '"';                    

IIRC geht das zumindest bei MySQL - man sollte nur die Anführungszeichen nicht innerhalb eines Querys wechseln ...


Tilman - Fr 07.08.09 00:17

Oh wo dus grad sagts, gehen in MySql nicht sogar Accents ´string´


Delete - Fr 07.08.09 09:34

Versucht mal, einen String einzutragen, der ein Anführungszeichen enthält.


delphijanka - Fr 07.08.09 12:59

man muss natürlich anmerken, dass je nach Datenbank die Quotes anders gesetzt werden sollen. Zum Beispiel geht bei MySQL "-Zeichen, bei Oracle nicht.


D. Annies - Di 11.08.09 22:01

Danke für eure Mühe,
Detlef


mkinzler - Mi 12.08.09 07:45

Zitat:
die aber imo beschäment ist (fu Delphi)
Beschämend finde ich eher das nicht auf gute oder weniger gute Lösungen gesetzt wird, sondern auf Biegen-und-Verderb versucht wird die möglichst schlechteste Lösunngsmöglichkeit zu finden.