Cómo pasar un array como parámetro a un procedimiento almacenado

prado
23 de Febrero del 2006
Hola,

Necesito insertar en una tabla de base de datos 5000 registros. Lo que estoy haciendo es llamar desde un servlet a un procedimento almacenado en una bd oracle, pasándole a este procedimiento los valores que debe insertar en la tabla.

Servlet:

for (int fila = 0; fila < 5000; fila++) {
CallableStatement cs = conn.prepareCall("{ call proInsertaPrueba ( ?,?,?,? ) }");
cs.setInt(1, 999);
cs.setInt(2, fila + 1);
cs.setString(3, “Valor”);
cs.setDouble(4, 4759.66);

ResultSet rsP = cs.executeQuery();
rsP.close();
cs.close();
} // end for


Procedimiento almacenado:

create procedure proInsertaPrueba (numCodigo IN NUMBER, numFila IN NUMBER, varValor IN VARCHAR2, numCantidad IN NUMBER)
IS
BEGIN
INSERT INTO PRUEBA_INSERT (Codigo, Fila, Valor, Cantidad)
VALUES (numCodigo, numFila , varValor, numCantidad);
COMMIT;
END;
/
El problema está en que tengo que llamar al procedimiento 5000 veces, ya que este procedimiento realiza una inserción en una tabla.

¿ Existe alguna manera de pasar la procedimiento almacenado un array ?

De tal forma que sólo haya que llamar al procedimiento un vez pasándole como parámetro un array de 5000 registros y este procedimiento almacenado se encargará de leer el array e realizar la inserciones en la tabla. Además de esta forma sólo hay un acceso a la base de datos.

Gracias de antemano.


geobasis
23 de Febrero del 2006
Hola si estas usando Oracle si hay forma si la BD es otra no lo se, en Oracle debes hacer algo asi:

Create or Replace TYPE Vector is varray(100) of varchar2(50); // Crear un Tipo de Dato Collection (VARRAY) especificar longitud maxima y tipo de dato de cada elemento

// Ejm de Procedimiento Almacenado
Procedure InsertVector(datos Vector) is
data varchar2(50);
i number;
p number;
begin
i:= datos.first(); p:=0;
while (p < datos.count()) loop
data:= datos(i);
dbms_output.put_line(data);
i:= datos.next(i);
p := p +1;
end loop;

end;

// Probar el Procedimiento almacenado desde un SQL window

declare
-- Non-scalar parameters require additional processing
datos Vector;
begin
-- Call the procedure
datos := Vector('Ecuador','Peru','Jamaica','Raul','Luis'); //cada elemento del VARRAY debe ir separado por comas

insertvector(datos => datos);

// invocar al Procedimiento desde JAVA

ArrayDescriptor arraydesc = ArrayDescriptor.createDescriptor
(Vector, connection); //Tipo de dato Collection y la conexion a la BD

ARRAY array = new ARRAY(arraydesc, connection, elements); // ArrayDescriptor, Conneccion a la BD y Array con los datos

OracleCallableStatement ocs =
(OracleCallableStatement)conn.prepareCall("{? = call insertVector()}");

ocs.setArray(index,array);
ocs.execute();
cerrar la conexion;

mas informacion la puedes encontrar en
http://www.stanford.edu/dept/itss/docs/oracle/9i/java.920/a96654/oraarr.htm o http://www.devx.com/tips/Tip/22034