2011-03-04 13 views

Respuesta

11

Aquí hay un ejemplo de cómo hacerlo.

El siguiente script configura una tabla, un tipo y un procedimiento almacenado en la base de datos. El procedimiento toma un parámetro del tipo de matriz e inserta cada fila de la matriz a la tabla:

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; 
/

el código Java a continuación demuestra que pasa una matriz en este procedimiento almacenado:

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(); 
    } 
} 

Si ejecuta el script SQL y luego la clase Java, y luego consultar la tabla strings, debe encontrar que todos los datos se han insertado en la tabla.

Cuando dices 'una matriz de caracteres', supongo que te refieres a una matriz de Java char s. Si he acertado, entonces creo que lo mejor sería convertir el char a String sy luego usar el mismo enfoque que el anterior.

+1

¿Es posible hacer esto con matrices multidimensionales? http://stackoverflow.com/questions/15045019/reading-an-oracle-nested-table-type-using-jdbc-for-an-oracle-type-with-more-than – ziggy

+0

He copiado/pegado toda la solución - resultando en "cadenas" de tablas que contienen tres valores (nulos) ... utilizando oracle 9i y 10g y todos los controladores jdbc disponibles - el resultado es el mismo. oracle.sql.ARRAY está vacío cuando se creó en Java - Estoy tratando de encontrar una solución, pero hasta ahora no hay suerte :(es el mismo problema que aquí http://stackoverflow.com/questions/14998299/oracle-array -filled-with-null-data-in-java – tomas

+1

incluyendo orai18n.jar debería resolver el problema - me ayudó en mi caso ... – tomas

3

vistazo aquí: http://download.oracle.com/docs/cd/B19306_01/java.102/b14355/oraarr.htm#i1058512

y aquí está mi pequeño ejemplo:

1) en la base de datos de

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) en Java

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); 
    } 
} 

parece funcionar: salida dice

to_string returned: abc;def;geh 
0

Puede utilizar los tipos de Oracle para asignar objetos Java a Oracle. Además, hay utilidades Spring JDBC.

0

Regex resolver

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

¿Está sugiriendo convertir la matriz en una 'cadena 'separada por comas y pasándola a un procedimiento esperando un' varchar2'; luego descomponiéndolo de nuevo a sus elementos? Eso parece desordenado, puede alcanzar el límite de tamaño de 32k y se romperá (posiblemente en silencio) si alguno de los valores ya contiene una coma ... –

0

Desde ArrayDescriptor está obsoleta desde 12c, no debe utilizarse más. He aquí una sniplet código que trabajó para mí en 12c:

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