我应该如何将键值传递给PL / SQL过程?

时间:2014-09-26 08:46:21

标签: java sql oracle plsql

首先,如果这是一个愚蠢的问题,我不得不道歉,但我是PL / SQL的新手。

我正在开发一个项目,需要使用java和PL / SQL与Oracle数据库进行一些交互。我有一个不确定的键值列表,我想传递给数据库,我的初步研究似乎指向oracle.sql.STRUCT和oracle.sql.ARRAY。

我并不完全支持STRUCT和ARRAY对象,因为它们需要数据库端的现有对象/表类型。

修改:

在我的pl / sql

CREATE OR REPLACE TYPE myItem AS object (c1 VARCHAR2(10), c2 VARCHAR2(30)); 
CREATE OR REPLACE TYPE text_table AS TABLE OF myItem ;

在我的java代码中

java.sql.Connection connection = myGetConnection();
// create variables for the oracle.sql.ARRAY
ArrayDescriptor arraydesc = ArrayDescriptor.createDescriptor("TEXT_TABLE", connection);
Object[] arrayObject = new Object[2];

//create STRUCT objects
StructDescriptor descriptor = StructDescriptor.createDescriptor("MYITEM", connection);

// Loop through the map and put objects in the arrayObject
for(int i = 0; i < myMap.size(); i++){
String key = "key"+1;
String value = "value"+2;
Object[] obj = {key,value};
STRUCT structObj = new STRUCT(descriptor, connection, obj);

// put the struct object in the array object
arrayObject[i] = structObj;
}

// create the oracle.sql.ARRAY
ARRAY array = new ARRAY(arraydesc, connection, arrayObject);

//..
oracleCallableStatement = connection.prepareCall("{call myPackage.myProcedure(?)}");
oracleCallableStatement.setArray(1, array);
oracleCallableStatement.execute();
oracleCallableStatement.close();

我必须在我的oracle数据库中激动地声明一个类型这一事实让我觉得必须有一种更简单的方法。这些都是非常原始的对象。

这是正确的方法,这是我唯一的选择吗?

1 个答案:

答案 0 :(得分:2)

这不是一个愚蠢的问题,你按照我的方式去做(所以我认为这是对的,至少!)。您必须能够将ARRAY类型与模式级集合类型相关联,因此必须使用SQL CREATE TYPE创建;它不能是一个包中定义的PL / SQL集合,比如,如果可能的话,它可能会有点整洁。 Oracle将Java数组映射到任意集合没有神奇的方法 - 您必须定义并关联该类型,以便可以通过JDBC在可识别的流中发送数据。

我可能考虑做的唯一不同的事情是将集合创建为表类型而不是varray

CREATE TYPE text_varray AS table OF myItem ;

...所以你不必限制大小;但元素的顺序可能很重要,只能由varray保留。

另一种选择是使用两个varrays,一个用于键,一个用于值,并将两个参数传递给您的过程;然后,您必须将原始Java二维数组转换为两个单独的数组。这样做的好处是您可以使用其中一种内置类型 - sys.odcivarchar2list - 而不必创建自己的varray或对象类型。但是由于它在Java方面更复杂,并且维护自己的类型并不是那么困难,它可能不值得;如果您从varray更改为table,则无法选择,因为两个列表中的元素不一定是相同的顺序。

如果对象定义中的字符串长度正确,则可能(ab)使用sys.odciobject and sys.odciobjectlist,因为这会给你一个类似的设置;但是,如果系统将来发生变化,使用您自己的类型仍然更安全,或者您的需求更改为需要更长的字符串。