# PreparedStatement IN-Funktion



## puls (22. Jan 2013)

Hey,

weiß jemand wie man ein PreparedStatement nutzt wenn man die Anzahl der Parameter nicht kennt?
Ich würde gerne die IN(Wert,Wert, ...)-Funktion nutzen aber ich kenne die Anzahl der Platzhalter erst zur Laufzeit.

Statische Platzhalter für 3 Parameter:

```
sql.executeQuery("SELECT * FROM tabelle WHERE ID IN(?,?,?)", idList);
```

So möchte ich das nicht lösen weil dann könnte ich statt die Platzhalten ja auch direkt die Werte setzen und dann wäre ja schon einige Vorteile von PreparedStatement wieder verloren.


```
sql.executeQuery("SELECT * FROM tabelle WHERE ID IN(" + getPaltzhalterstring(idList.size()) + ")", idList);
```

Danke für jeden Tipp


----------



## SlaterB (22. Jan 2013)

so viele Vorteile hat PreparedStatement ja nun auch nicht,
jeden Wert bei Übergabe auf korrekte Darstellung je nach DB/ Treiber zu formatieren, SQL-Injection zu verhindern, all das bleibt bestehen

es wäre freilich schön nur ein ? zu setzen und eine Liste per set-Methode zu übergeben, weniger Arbeit auch wenn sich intern nicht viel ändert (aber auf ?, ?, ? sicher auch verzichtet wird)
das gibt es z.B. in Hibernate, für PreparedStatement meines Wissens nicht,

womöglich mit der eigentlichen Aufgabe, die Query an die DB zum Prepare/ Vorbereiten zu schicken, unvereinbar, aber da spekuliere ich gerade nur ohne Eckkenntnisse

setArray() ist was anderes


----------



## puls (22. Jan 2013)

PreparedStatement sollen doch angeblich SQL-Injection verhindern oder zumind. die meisten Varianten davon. Außerdem führe ich die Queries Millionfach aus nur mit neuen Werten, PreparedStatement sind doch da schneller.


----------



## SlaterB (22. Jan 2013)

einfach so Sätze zu schreiben ohne genauen Bezug, da weiß ich zumindest nicht, ob auf mich bezogen, ob Widerrede, ob Thema beendet oder was auch immer

dass du mit zusammengebauter ?-Reihe + Parameterübergabe genau noch SQL-Injection-Schutz erhälst, habe ich ja gesagt,

-----

und dass die Wiederverwendung mit neu zusammengebauten Queries wegfällt ist klar,
ob sie überhaupt möglich ist wäre eine Frage, wie ich schon schrieb bezweifle ich das,

gut, zu diesem Punkt kann ich praktisch nur wiederholen dass ich nichts genaues weiß


----------



## r.w. (22. Jan 2013)

Ich mal hab irgendwo gelesen, dass das z.B. mit setObject in Verbindung mit einem String-Array
funktionieren soll. Hab es aber selbst noch nicht getestet, also schlagt mich nicht. ;-)


----------



## Timothy Truckle (22. Jan 2013)

puls hat gesagt.:


> PreparedStatement sollen doch angeblich SQL-Injection verhindern oder zumind. die meisten Varianten davon. Außerdem führe ich die Queries Millionfach aus nur mit neuen Werten, PreparedStatement sind doch da schneller.


Also ich spinne mal in's Blaue und vermute, das die Werte in der 
	
	
	
	





```
IN
```
 Klausel numerische ID's sind. In diesem Fall sollten die ja auch zu dem Zeitpunkt, zu dem die Query gebaut wird, als Zahlentypen vor liegen. Damit ist SQL-Injection schon mal kein Thema mehr.

Bleibt der Performance-verlust durch hard parsing des Statements in der DB. Der dürfte aber IMHO gegenüber dem Overhead, den die "eche" Lösung (mittes Database-Array-Types) erfordert nicht relevant sein.

Zu beachten ist eigentlich nur, dass man bei Oracle -DB,s nur maximal 999 literale Werte angeben darf. Das kann bei anderen DB's natürlich anderes sein...

Andererseits lohnt es sich vielleicht die Selects als Batch abzusetzen 
	
	
	
	





```
for (BigDecimal nextId : idSet){
  ps.setBigDecimal(nextId);
  ps.addBatch();
}
ps.executeBatch();
ResultSet rs= ps.getResultSet();
```
[EDIT]Das habe ich aber selbst noch nicht eingesetzt...[/EDIT]

bye
TT


----------



## Timothy Truckle (22. Jan 2013)

r.w. hat gesagt.:


> Ich mal hab irgendwo gelesen, dass das z.B. mit setObject in Verbindung mit einem String-Array
> funktionieren soll. Hab es aber selbst noch nicht getestet, also schlagt mich nicht. ;-)


Das hast Du falsch gehört.

bye
TT


----------



## puls (22. Jan 2013)

Okey danke erstmal an alle. Dann werde ich das erstmal so lassen.


----------



## Timothy Truckle (22. Jan 2013)

SlaterB hat gesagt.:


> und dass die Wiederverwendung mit neu zusammengebauten Queries wegfällt ist klar,
> ob sie überhaupt möglich ist wäre eine Frage, wie ich schon schrieb bezweifle ich das,


Ich sag mal so:
Die Wahrscheilichkeit dafür, dass ein weiteres Statement mit der selben Anzahl 
	
	
	
	





```
?
```
 erzeugt wird ist wesentlich höher als dafür, dass ein weiteres Statement mit genau den selben ID's in genau der selben Reihenfolge erstellt wird....

bye
TT


----------

