Fra SQL-siden kan du definere en tabeltype og bruge den til at forbinde til dine rigtige data, sådan som:
opret type min_array_type som tabel med tal/opret eller erstat funktion f42 (in_array my_array_type)retur sys_refcursor som rc sys_refcursor;begynd åben rc for at vælge a.column_value som id, tilfælde hvor t.id er null og derefter 'mangler ' ellers slutter 'present' som status fra tabel(in_array) a left join t42 t on t.id =a.column_value rækkefølge efter id; returner rc;end f42;/
SQL Fiddle-demo med en indpakningsfunktion, så du kan forespørge den direkte, hvilket giver:
ID STATUS ---------- -------------------- 1 til stede 2 til stede 3 til stede 4 mangler 8 mangler 23 til stede
Fra Java kan du definere en ARRAY
baseret på tabeltypen, udfyld fra et Java-array og kald funktionen direkte; din single parameter bind variabel er ARRAY
, og du får et resultatsæt tilbage, som du kan gentage som normalt.
Som en oversigt over Java-siden:
int[] ids ={ 1, 2, 3, 4, 8, 23 };ArrayDescriptor aDesc =ArrayDescriptor.createDescriptor("MY_ARRAY_TYPE", conn);oracle.sql.ARRAY ora_ids =new oracle.sql .ARRAY(aDesc, conn, ids);cStmt =(OracleCallableStatement) conn.prepareCall("{ call ? :=f42(?) }");cStmt.registerOutParameter(1, OracleTypes.CURSOR);cStmt.setArray(2, ora_ids);cStmt.execute();rSet =(OracleResultSet) cStmt.getCursor(1);while (rSet.next()){ System.out.println("id " + rSet.getInt(1) + ":" + rSet.getString(2));}
Hvilket giver:
id 1:presentid 2:presentid 3:presentid 4:missingid 8:missingid 23:present
Som Maheswaran Ravisankar nævner, tillader dette et hvilket som helst antal elementer at blive bestået; du behøver ikke at vide, hvor mange elementer der er på kompileringstidspunktet (eller omhandler et teoretisk maksimum), du er ikke begrænset af det maksimale antal udtryk, der er tilladt i en IN
eller ved længden af en enkelt afgrænset streng, og du behøver ikke at komponere og dekomponere en streng for at sende flere værdier.
Som ThinkJet påpegede, hvis du ikke ønsker at oprette din egen tabeltype, kan du bruge en foruddefineret samling, vist her; hovedfunktionen er den samme bortset fra erklæringen af parameteren:
opret eller erstat funktion f42 (in_array sys.odcinumberlist)retur sys_refcursor som...
Indpakningsfunktionen udfylder arrayet lidt anderledes, men på Java-siden behøver du kun at ændre denne linje:
ArrayDescriptor aDesc =ArrayDescriptor.createDescriptor("SYS.ODCINUMBERLIST", conn );
At bruge dette betyder også (som ThinkJet også påpegede!), at du kan køre din originale selvstændige forespørgsel uden at definere en funktion:
vælg a.column_value som id, tilfælde, når t.id er null, og derefter 'missing'else 'present' end som statusfrom table(sys.odcinumberlist(1, 2, 3, 4, 8, 23)) aleft join t42 t on t.id =a.column_valueorder by id;
(SQL Fiddle).
Og det betyder, at du kan kalde forespørgslen direkte fra Java:
int[] ids ={ 1, 2, 3, 4, 8, 23 };ArrayDescriptor aDesc =ArrayDescriptor.createDescriptor("SYS.ODCINUMBERLIST", conn );oracle.sql.ARRAY ora_ids =nyt orakel .sql.ARRAY(aDesc, conn, ids);sql ="vælg a.column_value som id, " + "tilfælde, når t.id er null, derefter 'mangler' " + "ellers 'nuværende' slutter som status " + "fra table(?) a " + "venstre join t42 t on t.id =a.column_value " + "order by id";pStmt =(OraclePreparedStatement) conn.prepareStatement(sql);pStmt.setArray(1, ora_ids);rSet =(OracleResultSet) pStmt.executeQuery();while (rSet.next()){ System.out.println("id " + rSet.getInt(1) + ":" + rSet.getString(2));}
... som du måske foretrækker.
Der er en foruddefineret ODCIVARCHAR2LIST
skriv også, hvis du rent faktisk sender strenge - din originale kode ser ud til at arbejde med strenge, selvom de indeholder tal, så du er ikke sikker på, hvilken du virkelig har brug for.
Fordi disse typer er defineret som VARRAY(32767)
du er begrænset til 32k værdier, mens definering af din egen tabel fjerner den begrænsning; men det betyder selvfølgelig kun noget, hvis du videregiver en masse værdier.