Dari sisi SQL, Anda dapat menentukan tipe tabel dan menggunakannya untuk bergabung dengan data asli Anda, seperti:
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;
/
Demo SQL Fiddle dengan fungsi pembungkus sehingga Anda dapat menanyakannya secara langsung, yang memberikan:
ID STATUS
---------- --------------------
1 present
2 present
3 present
4 missing
8 missing
23 present
Dari Java Anda dapat menentukan ARRAY
berdasarkan tipe tabel, isi dari array Java, dan panggil fungsi secara langsung; variabel pengikatan parameter tunggal Anda adalah ARRAY
, dan Anda mendapatkan kembali kumpulan hasil yang dapat Anda ulangi seperti biasa.
Sebagai garis besar dari sisi Java:
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));
}
Yang memberikan:
id 1: present
id 2: present
id 3: present
id 4: missing
id 8: missing
id 23: present
Seperti yang disebutkan Maheswaran Ravisankar, ini memungkinkan sejumlah elemen untuk dilewati; Anda tidak perlu tahu berapa banyak elemen yang ada pada waktu kompilasi (atau berurusan dengan maksimum teoritis), Anda tidak dibatasi oleh jumlah maksimum ekspresi yang diizinkan dalam IN
atau dengan panjang string tunggal yang dibatasi, dan Anda tidak perlu membuat dan menguraikan string untuk meneruskan beberapa nilai.
Seperti yang ditunjukkan oleh ThinkJet, jika Anda tidak ingin membuat tipe tabel Anda sendiri, Anda dapat menggunakan koleksi yang telah ditentukan sebelumnya, yang ditunjukkan di sini; fungsi utama adalah sama selain dari deklarasi parameter:
create or replace function f42 (in_array sys.odcinumberlist)
return sys_refcursor as
...
Fungsi pembungkus mengisi array sedikit berbeda, tetapi di sisi Java Anda hanya perlu mengubah baris ini:
ArrayDescriptor aDesc =
ArrayDescriptor.createDescriptor("SYS.ODCINUMBERLIST", conn );
Menggunakan ini juga berarti (seperti yang juga ditunjukkan oleh ThinkJet!) bahwa Anda dapat menjalankan kueri asli yang berdiri sendiri tanpa mendefinisikan fungsi:
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 Fiddle).
Dan itu berarti Anda dapat memanggil kueri langsung dari Java:
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));
}
... yang mungkin Anda sukai.
Ada ODCIVARCHAR2LIST
yang telah ditentukan sebelumnya ketik juga, jika Anda benar-benar melewatkan string - kode asli Anda tampaknya berfungsi dengan string meskipun berisi angka, jadi tidak yakin mana yang benar-benar Anda butuhkan.
Karena tipe ini didefinisikan sebagai VARRAY(32767)
Anda dibatasi hingga 32k nilai, sementara mendefinisikan tabel Anda sendiri menghilangkan batasan itu; tapi jelas itu hanya penting jika Anda melewati banyak nilai.