Von der SQL-Seite aus könnten Sie einen Tabellentyp definieren und diesen verwenden, um ihn mit Ihren echten Daten zu verknüpfen, etwa so:
create type my_array_type as table of number
/
create or replace function f42 (in_array my_array_type)
return sys_refcursor as
rc sys_refcursor;
begin
open rc for
select a.column_value as id,
case when t.id is null then 'missing'
else 'present' end as status
from table(in_array) a
left join t42 t on t.id = a.column_value
order by id;
return rc;
end f42;
/
SQL Fiddle-Demo mit einer Wrapper-Funktion, damit Sie sie direkt abfragen können, was Folgendes ergibt:
ID STATUS
---------- --------------------
1 present
2 present
3 present
4 missing
8 missing
23 present
Von Java aus können Sie ein ARRAY
definieren basierend auf dem Tabellentyp aus einem Java-Array füllen und die Funktion direkt aufrufen; Ihre Einzelparameter-Bind-Variable ist das ARRAY
, und Sie erhalten eine Ergebnismenge zurück, über die Sie wie gewohnt iterieren können.
Als Umriss der Java-Seite:
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));
}
Was ergibt:
id 1: present
id 2: present
id 3: present
id 4: missing
id 8: missing
id 23: present
Wie Maheswaran Ravisankar erwähnt, erlaubt dies, eine beliebige Anzahl von Elementen zu übergeben; Sie müssen nicht wissen, wie viele Elemente zur Kompilierzeit vorhanden sind (oder mit einem theoretischen Maximum umgehen), Sie sind nicht durch die maximale Anzahl von Ausdrücken begrenzt, die in einem IN
zulässig sind oder durch die Länge einer einzelnen Zeichenfolge mit Trennzeichen, und Sie müssen eine Zeichenfolge nicht zusammensetzen und zerlegen, um mehrere Werte zu übergeben.
Wie ThinkJet betonte, können Sie, wenn Sie keinen eigenen Tabellentyp erstellen möchten, eine vordefinierte Sammlung verwenden, die hier demonstriert wird. die Hauptfunktion ist die gleiche abgesehen von der Deklaration des Parameters:
create or replace function f42 (in_array sys.odcinumberlist)
return sys_refcursor as
...
Die Wrapper-Funktion füllt das Array etwas anders, aber auf der Java-Seite müssen Sie nur diese Zeile ändern:
ArrayDescriptor aDesc =
ArrayDescriptor.createDescriptor("SYS.ODCINUMBERLIST", conn );
Wenn Sie dies verwenden, bedeutet dies auch (wie ThinkJet auch darauf hingewiesen hat!), dass Sie Ihre ursprüngliche eigenständige Abfrage ausführen können, ohne eine Funktion zu definieren:
select a.column_value as id,
case when t.id is null then 'missing'
else 'present' end as status
from table(sys.odcinumberlist(1, 2, 3, 4, 8, 23)) a
left join t42 t on t.id = a.column_value
order by id;
(SQL-Geige).
Und das bedeutet, dass Sie die Abfrage direkt aus Java heraus aufrufen können:
int[] ids = { 1, 2, 3, 4, 8, 23 };
ArrayDescriptor aDesc = ArrayDescriptor.createDescriptor("SYS.ODCINUMBERLIST", conn );
oracle.sql.ARRAY ora_ids = new oracle.sql.ARRAY(aDesc, conn, ids);
sql = "select a.column_value as id, "
+ "case when t.id is null then 'missing' "
+ "else 'present' end as status "
+ "from table(?) a "
+ "left 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));
}
... was Ihnen vielleicht lieber ist.
Es gibt eine vordefinierte ODCIVARCHAR2LIST
Geben Sie auch ein, wenn Sie tatsächlich Zeichenfolgen übergeben - Ihr ursprünglicher Code scheint mit Zeichenfolgen zu arbeiten, obwohl sie Zahlen enthalten, also sind Sie sich nicht sicher, welche Sie wirklich brauchen.
Weil diese Typen als VARRAY(32767)
definiert sind Sie sind auf 32.000 Werte beschränkt, während die Definition Ihrer eigenen Tabelle diese Einschränkung aufhebt; aber das spielt natürlich nur eine Rolle, wenn Sie viele Werte übergeben.