2008-11-19 9 views
5

Je me demandais s'il y avait un moyen de lier un ArrayList (ou n'importe quel type de liste, d'ailleurs) à un PreparedStatement qui sera finalement utilisé pour accéder à une base de données Oracle. J'ai trouvé:Comment associer une ArrayList à PreparedStatement dans Oracle?

PreparedStatement IN clause alternatives?

et qui semble similaire à ma question, mais cette question est plus spécifique: Je voudrais lier un ArrayList à un PreparedStatement à utiliser dans Oracle, si elle est possible, comment est-ce accompli?

+0

En quelle capacité? À quoi ressemble votre déclaration (avec des espaces réservés)? Je doute qu'il y ait une solution générale à cela puisque 1) la longueur de la liste variera et 2) le nombre d'espaces réservés dans votre déclaration ne le sera probablement pas. De plus, toutes les listes ne sont pas commandées. –

+0

Matt, tous les objets qui implémentent java.util.List fournissent une opération get (int) qui récupère l'objet à l'index spécifié. Il fournit également un itérateur. Les deux sont non-optionnels: l'ordre peut être impair, mais une commande existe. Donc, toutes les implémentations java.util.List * sont * commandées ... – MetroidFan2002

+0

... et, en Java, List fait généralement référence au contrat d'interface java.util.List. – MetroidFan2002

Répondre

5

Vous ne pouvez pas lier une liste à un seul paramètre dans une déclaration préparée.

Générer SQL avec le marqueur de paramètre pour chaque élément dans la liste, par exemple:

SELECT NAME FROM ITEM WHERE ID IN (?, ?, ?, ?) 

Même si vous allez générer une nouvelle déclaration pour chaque requête, je vous recommande encore l'aide d'un PreparedStatement. Si votre liste contient String instances, vous obtiendrez l'échappement nécessaire pour protéger de l'injection SQL.

Mais même si c'est un type sûr, comme Integer objets, certains pilotes ou middleware peuvent mettre en cache PreparedStatements et renvoyer une instance mise en cache si le même formulaire est demandé. Bien sûr, certains tests seraient nécessaires. Si la taille de vos listes varie considérablement, vous disposerez de nombreuses instructions différentes et un cache mal implémenté risque de ne pas être prêt à en traiter autant.

+0

C'est ce dont j'avais peur, mais il semble que vous deviez générer une "chaîne de point d'interrogation" et l'ajouter à votre instruction SQL générale. Tant pis. – MetroidFan2002

3

Vous ne pouvez pas lier directement. Il existe un moyen de passer un tableau en tant que paramètre. Je n'ai aucune idée de ce que vous voulez en faire du côté de la base de données, cela ne vous aidera peut-être pas.

Fondamentalement, vous devez créer un type de table imbriqué dans la base de données; construire un objet Java basé sur ce type, contenant les données de votre tableau; et passez cela comme paramètre.

Si vous avez créé ces objets dans la base de données:

CREATE OR REPLACE TYPE my_nested_table IS TABLE OF VARCHAR2(20); 
CREATE TABLE my_table (a my_nested_table) NESTED TABLE a STORE AS my_table_a; 

Ensuite, vous pouvez écrire du code Java comme ceci:

String[] insertvalues = { "a", "b", "c" }; 
PreparedStatement p = conn.prepareStatement("INSERT INTO my_table VALUES(?)"); 
ARRAY insertParameter = new ARRAY(a_desc, conn, insertvalues); 
p.setArray(1, insertParameter); 
p.execute(); 

Les résultats Oracle ressemblent à ceci:

dev> select * from my_table; 

A 
-------------------------------------------------------------------------------- 
MY_NESTED_TABLE('a', 'b', 'c')