2011-03-04 25 views
6

Oracle'ın iki yordamını, Oracle'ın saklı yordamlarına göndermek istiyorum. İlk Array dizgileri dizisidir ve ikincisi karakter dizisidir. Bunu nasıl yapabilirim? Buradadiziyi oracle yordamına geçirme

cevap

11

İşte nasıl yapılacağına dair bir örnek.

Aşağıdaki komut dosyası, veritabanında bir tablo, bir tür ve saklı yordamlar oluşturur. Prosedür düzen tipinde bir parametre alır ve tabloya dizinin her satır ekler:

CREATE TABLE strings (s VARCHAR(4000)); 

CREATE TYPE t_varchar2_array AS TABLE OF VARCHAR2(4000); 
/

CREATE OR REPLACE PROCEDURE p_array_test(
    p_strings  t_varchar2_array 
) 
AS 
BEGIN 
    FOR i IN 1..p_strings.COUNT 
    LOOP 
    INSERT INTO strings (s) VALUES (p_strings(i)); 
    END LOOP; 
END; 
/

sonra bu saklı yordam içine bir dizi geçirilmesi gösterilmektedir Java kodu:

import java.sql.*; 
import oracle.jdbc.*; 
import oracle.sql.*; 

public class ArrayTest { 
    public static void main(String[] args) throws Exception { 
     DriverManager.registerDriver(new OracleDriver()); 
     Connection conn = DriverManager.getConnection(
      "jdbc:oracle:thin:@localhost:1521:xe", "user", "pass"); 

     CallableStatement stmt = conn.prepareCall("BEGIN p_array_test(?); END;"); 

     // The first parameter here should be the name of the array type. 
     // It's been capitalised here since I created it without using 
     // double quotes. 
     ArrayDescriptor arrDesc = 
      ArrayDescriptor.createDescriptor("T_VARCHAR2_ARRAY", conn); 

     String[] data = { "one", "two", "three" }; 
     Array array = new ARRAY(arrDesc, conn, data); 
     stmt.setArray(1, array); 
     stmt.execute(); 

     conn.commit(); 
     conn.close(); 
    } 
} 

Eğer kaçarsan SQL komut dosyasını ve ardından Java sınıfını ve ardından tabloyu strings sorgulayın, tüm verilerin tabloya eklendiğini görmelisiniz.

'Bir dizi karakter' derken, bir dizi Java char s olduğunu tahmin ediyorum. Doğru tahmin edersem, o zaman char s 'yi String s' ye dönüştürmek ve daha sonra yukarıdakiyle aynı yaklaşımı kullanmaktan daha iyi olacağını düşünüyorum.

+1

bu çok boyutlu diziler ile yapmak mümkün mü? http://stackoverflow.com/questions/15045019/reading-an-oracle-nested-table-type-using-jdbc-for-an-oracle-type-with-more-than – ziggy

+0

Tüm çözümünüzü kopyala/yapıştır - oracle 9i'nin yanı sıra 10g ve tüm mevcut jdbc sürücüleri kullanılarak üç (boş) değer içeren tablo "dizeleri" ile sonuçlanır - sonuç aynıdır. java'da oluşturulduğunda oracle.sql.ARRAY boş - çözüm bulmaya çalışıyorum ama şu ana kadar şansınız yok: (http://stackoverflow.com/questions/14998299/oracle-array orai18n.jar dahil olmak üzere-null-veri-içinde-null-data-in-java – tomas

+1

sorunu çözmelidir - benim durumumda yardımcı oldu ... – tomas

3

Görünüş: Burada http://download.oracle.com/docs/cd/B19306_01/java.102/b14355/oraarr.htm#i1058512

ve benim kısa örnektir:

1) java veritabanı

SQL> create or replace type string_array as table of varchar2(100); 
    2/

Type created. 

SQL> create or replace function to_string(p_array in string_array) return varchar2 
    2 as 
    3  l_string varchar2(32767); 
    4  i binary_integer; 
    5 begin 
    6  i := p_array.first(); 
    7  while i is not null loop 
    8  l_string := l_string || p_array(i) || ';'; 
    9  i := p_array.next(i); 
10  end loop; 
11  l_string := rtrim(l_string, ';'); 
12  return l_string; 
13 end; 
14/

Function created. 

2) üzerinde

public class ArrayTest { 
    public static void main(String[] args) throws SQLException { 
     DriverManager.registerDriver(new OracleDriver()); 
     OracleConnection connection = (OracleConnection) DriverManager.getConnection(...); 

     String[] elements = {"abc", "def", "geh"}; 
     ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor("STRING_ARRAY", connection); 
     ARRAY array = new ARRAY(descriptor, connection, elements); 

     OracleCallableStatement stmt = (OracleCallableStatement) connection.prepareCall("{? = call to_string(?)}"); 
     stmt.registerOutParameter(1, Types.VARCHAR); 
     stmt.setARRAY(2, array); 
     stmt.execute(); 

     String result = stmt.getString(1); 
     System.out.println("to_string returned: " + result); 
    } 
} 

iş gibi görünüyor: çıktı diyor

to_string returned: abc;def;geh 
0

Java nesnelerini Oracle'a eşlemek için Oracle Türlerini kullanabilirsiniz. Ayrıca, Spring JDBC yardımcı programları var.

0

Regex ArrayDescriptor yana

select * from table_a a where a.col in (select regexp_substr('SMITH,ALLEN,WARD,JONES','[^,]+', 1, level) from dual 
connect by regexp_substr('SMITH,ALLEN,WARD,JONES', '[^,]+', 1, level) is not null;) 
+2

Diziyi virgülle ayrılmış bir "String" 'e dönüştürmeyi ve bir varchar2'yi bekleyen bir prosedüre geçirmeyi önerir misiniz? daha sonra onu elemanlarına geri mi ayırıyor? Bu dağınık görünüyor, 32k boyut sınırına vurabilir ve herhangi bir değer zaten virgül içeriyorsa (muhtemelen sessizce) kırılacak ... –

0

12c beri, artık kullanılmamalıdır kullanımdan kaldırıldı çözmek. İşte 12c benim için çalışan bir kod sniplet var:

  Array array = ((OracleConnection) connection).createOracleArray("T_VARCHAR2_ARRAY", data); 
      CallableStatement statement = connection.prepareCall("{call p_array_test(?)}"); 
      statement.setArray(1, array); 
      statement.execute();