Entwickler-Ecke

Datenbanken - SQL Abfrage mit "in"


mirko07 - Mo 26.01.09 22:09
Titel: SQL Abfrage mit "in"
Hallo Leute!
Ich hab ein Problem mit Delphi 6.
Ich möchte über ein ADOQuery eine Abfrage machen in Sinne von:
select * from tabelle where stadt in (:stadt)
:stadt ist ein String-Parameter der übergeben wird in der Form: 'Leipzig','Düsseldorf'...
Das funktioniert nicht. Ohne Anführungsstriche klappt es mit einer Stadt. Mit mehreren nicht.
Ich hab in Turorials nachgesehen und mach es eigentlich richtig.
Kann mir da jemand helfen?

Mirko


Moderiert von user profile iconNarses: Topic aus Dateizugriff verschoben am Di 27.01.2009 um 16:57


Niko S. - Mo 26.01.09 22:16

Ich hab solche Probleme auch manchmal... Meistens klappt es dann mit "AND" statt den Kommata aber das sieht nicht so schön aus ...


Sinspin - Mo 26.01.09 22:26

Zeig mal deinen Quelltext wie es nicht geht.
Ansonsten: Beachtest du das jeder einzelne Wert in Hochkomma muss? (nicht das Komma dazwischen mit erwischen).
Versuch es erstmal ohne Parameter und mit fest eingetragenen Werten.


mirko07 - Di 27.01.09 16:49

Vielen Dank rfür Eure Mühen.
Das ist leider alles nicht zielführend.
Direkteintragen ging nicht. Egal welche Anführungszeichen ich versucht habe.
Auf den Parameter kann ich nicht verzichten, da die Städte dynamisch aus einer Liste geladen werden.


Niko S. - Di 27.01.09 16:53

wäre es nicht das selbe wenn du statt WHERE stadt IN einfach
WHERE stadt LIKE 'Leipzig','Duesseldorf'...
?


Regan - Di 27.01.09 17:00

user profile iconNiko S. hat folgendes geschrieben Zum zitierten Posting springen:
wäre es nicht das selbe wenn du statt WHERE stadt IN einfach
WHERE stadt LIKE 'Leipzig','Duesseldorf'...
?

Nein, das ist nicht ganz exakt. Mit = und somit auch mit IN prüfst du auf Gleichheit, mit LIKE kannst du auch noch auf mehr Sachen prüfen (in Kombination mit % und _ z.B.).


Niko S. - Di 27.01.09 17:48

Okay stimmt schon aber es ist doch so dass es nicht funktioniert mit der auflistung ... warum gehts denn nicht mit "AND" außer dass es nicht so schön aussieht amsonsten doch nur mal zu testzwecken das bei pma oder so reinsetzen o:
Ich versuch ja nur zu helfen .. :x


Sinspin - Di 27.01.09 18:22

Wie schon gesagt, zeig mal deinen Quelltext, vieleicht ist ein Fehler an einer Stelle der dir einfach nicht auffällt.
..oder dein fertiges SQL Statement.

Mein Versuch mit IN hat problemlos geklappt. (Datenbank Advantage)

SQL-Anweisung
1:
select * from countries where name in ('ARUBA', 'ARMENIA')                    

Ich habe wie erwartet zwei Datensätze bekommen.


Nersgatt - Mi 28.01.09 08:09

user profile iconSinspin hat folgendes geschrieben Zum zitierten Posting springen:
Mein Versuch mit IN hat problemlos geklappt. (Datenbank Advantage)

SQL-Anweisung
1:
select * from countries where name in ('ARUBA', 'ARMENIA')                    

Ich habe wie erwartet zwei Datensätze bekommen.

Dann schreib mal bitte Deine Abfrage so um, dass ARUBA und ARMENIA nicht fest codiert sind, sondern dass man sie als Parameter übergeben kann. Ich denke, das ist das Problem.


alzaimar - Mi 28.01.09 08:31

Ein Parameter in einer Query ist kein Platzhalter!

Die Liste der 'IN' Klausel kannst Du nicht korrekt parametrieren, denn Delphi wird um den String nochmal Hochkommata legen und die Hochkommata im ursprünglichen String 'escapen', d.h. verdoppeln, sodaß die Query letztendlich so aussieht:

SQL-Anweisung
1:
select * in tabelle where feld in ('''Leipzig'',''Dresden''')                    

Somit liefert diese Abfrage, bei denen feld = 'Leipzig','Dresden' ist, was doch ziemlich selten vorkommt.

Du musst dir dein SELECT selbst zusammenbauen, z.B. mit der Formatanweisung:

Delphi-Quelltext
1:
2:
StaedteListe := QuotedStr('Leipzig')+','+QuotedStr('Dresden');
MyQuery.SQL.Text := Format('select * in tabelle where feld in (%s),[Staedteliste]));

Dann sollte das auch funktionieren.


ene - Mi 28.01.09 08:35

Und wenn du es in 2 Variablen machst?


Delphi-Quelltext
1:
2:
3:
4:
5:
var strKrit, strSQL: String;
Begin
  strKrit:= '"ARUBA", "ARMENIA"';
  strSQL:= 'SELECT * FROM Tabelle WHERE Feld In (' + strKrit + ')';
End;


Nersgatt - Mi 28.01.09 08:40

Das ist sehr schade, dass man mit IN keine echten Parameter nutzen kann. Beim Zusammensetzen der SQL-Strings müsste man ja z.B. auch an Problemfälle wie z.B. SQL-Injection denken und z.B. das ' richtig maskieren.


ene - Mi 28.01.09 09:22

In() macht eigentlich nur Sinn, wenn die Werte aus einer Usereingabe resultieren, die nirgends gespeichert ist. Ansonsten kann man mit LEFT JOIN's und Prüfungen auf Null/Nicht Null das gleiche erreichen und im Gegensatz zu Not In() auch noch Zeit sparen.


Delete - Mi 28.01.09 16:22

Wobei das DBMS nach meinem Kenntnisstand aus dem "in" sowieso intern eine OR-Verkettung macht.


Martok - Mi 28.01.09 16:38

Nein, IN ist eine Subquery, läuft auf

SQL-Anweisung
1:
where exists (select wert from {Pseudo-Tabelle mit den Werten})                    

hinaus.

Oh, und bei Oracle/DOA nimmt man dafür dann den Parameter-Typ Substitution. Keine Ahnung, obs den bei anderen auch gibt... Nur dass die dann wieder genauso Injection-Anfällig sind, da sie noch vorm Parsen ersetzt werden. Aber immerhin schon Serverseitig ;)