[Java/JDBC] PreparedStatement voor variable IN parameters

Pagina: 1
Acties:

  • ari3
  • Registratie: Augustus 2002
  • Niet online
Stel je hebt een prepared statement als volgt:
SQL:
1
SELECT iets FROM tabel WHERE iets IN (?)

Hoe doe ik dit als prepared statement in Java/JDBC wanneer de IN-clausule een variabel aantal waarden kan bevatten? Op dit moment lukt me dat alleen met zoiets als hieronder:
Java:
1
2
3
4
5
6
7
8
9
10
public void zoek(List<String> lijst) throws Exception {
    String query = "SELECT iets FROM tabel WHERE iets IN (?)";
    Connection con = null; // getConnection();
    PreparedStatement ps = con.prepareStatement(query);
    for (String s : lijst) {
        ps.setString(1, s);
        ResultSet rs = ps.executeQuery();
        // ... doe hier iets met result set ...
    }
}

Dit is natuurlijk een erg lelijke en inefficiënte oplossing. Ik wil eigenlijk een setString die een List, Collection of array accepteert. Ik met nadruk bovenstaande oplossing niet gebruiken. Ook wil ik niet zelf de querystring samenstellen. Het moet beslist een prepared statement zijn. Ik heb gegoogled maar geen passende oplossingsrichting kunnen vinden. Het lijkt echt alsof de JDBC-API serieus gehandicapt is met betrekking tot dynamische IN-parameters?

"Kill one man, and you are a murderer. Kill millions of men, and you are a conqueror. Kill them all, and you are a god." -- Jean Rostand


  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06-2025

Varienaja

Wie dit leest is gek.

ari3 schreef op donderdag 22 september 2005 @ 22:30:
Het lijkt echt alsof de JDBC-API serieus gehandicapt is met betrekking tot dynamische IN-parameters?
Nounounou..


for i:=1 to lengte(lijst) {
sql.add('?, ');
}

for i:=1 to lengte(lijst) {
bindparam(i,lijst[i]);
}

Een beetje knutselen kan geen kwaad natuurlijk.

Sommige databases (van Oracle weet ik het zeker) accepteren een maximaal aantal elementen in een in-gedeelte. Als je dat op bovenstaande manier uitvoert ligt dat aantal op 256 geloof ik.

Siditamentis astuentis pactum.


  • ari3
  • Registratie: Augustus 2002
  • Niet online
Varienaja schreef op donderdag 22 september 2005 @ 23:07:
for i:=1 to lengte(lijst) {
sql.add('?, ');
}

for i:=1 to lengte(lijst) {
bindparam(i,lijst[i]);
}
Dat is dus precies wat ik bedoelde met "niet zelf de query string samenstellen". Uit jouw pseudo code blijkt meteen al dat het plaatsen van de komma problematisch is. Het is gewoon geen elegante oplossing. Ik wil dat de database engine het werk doet i.p.v. de client.

"Kill one man, and you are a murderer. Kill millions of men, and you are a conqueror. Kill them all, and you are a god." -- Jean Rostand


  • Glabbeek
  • Registratie: Februari 2001
  • Laatst online: 30-04 09:43

Glabbeek

Dat dus.

Het klopt dat het niet kan. Ik ben ook op zoek gegaan naar een oplossing toen ik van de week tegen hetzelfde probleem aanliep, maar ben tot de conclusie gekomen dat het in-statement niet echt ondersteund wordt in een java.sql.PreparedStatement. Uiteindelijk heb ik de manier zoals de Varienaja in pseudo-code aangeeft gebruikt, maar daardoor kunnen de PreparedStatement query strings niet meer als private static final gecodeerd worden, wat in sommige gevallen weer wat performance-verlies kan geven. Gelukkig valt het vaak in het niet met de kosten van een SQL-query.

Je kan dus het beste een String opbouwen via een StringBuffer met zoveel vraagtekens als je in je IN-statement wilt hebben, helaas.

[ Voor 4% gewijzigd door Glabbeek op 22-09-2005 23:36 ]

En zo is het maar net.


  • momania
  • Registratie: Mei 2000
  • Laatst online: 17:35

momania

iPhone 30! Bam!

Je zou er eventueel een stored procedure van kunnen maken, maar zoals Varienaja al aangeeft is dat gewoon de manier om dit op te lossen.

Gebruik van de 'where x in (y,z,..)' wordt toch vaak afgeraden (vanwege performance) en is vaak ook niet eens nodig.

Neem je whisky mee, is het te weinig... *zucht*