【问题标题】:Call oracle stored procedure with oracle object parameter使用 oracle 对象参数调用 oracle 存储过程
【发布时间】:2019-10-29 02:22:43
【问题描述】:

我将oracleojdbc 版本从11.1.0.2 升级到12.1.0.2。我想将 oracle 对象类型的 array 作为参数提供给 oracle procedure。此过程在 oracle 端采用 2 个varchar2 参数。例如,我将 3 个对象作为键值对数组发送,oracle 接受这些对象。我的问题是(varchar2 类型的)参数在调用我的过程时为空。

这是我尝试过的代码。

OracleConnection oraconn = conn.unwrap(OracleConnection.class);
Struct[] paramStructArray = new Struct[3];
paramStructArray[0] = oraconn.createStruct("KEY_VALUE_ENTRY",new Object[]{"key1","value1"});
paramStructArray[1] = oraconn.createStruct("KEY_VALUE_ENTRY",new Object[]{"key2","value2"});
paramStructArray[2] = oraconn.createStruct("KEY_VALUE_ENTRY",new Object[]{"key3","value3"});
Array array = oraconn.createOracleArray("KEY_VALUE_MAP", paramStructArray);

CallableStatement cstmt = getStatement(Statement.REGISTER_REQUEST);
cstmt.setString(1, requestId);
cstmt.setArray(2, array);
cstmt.execute();

这是我的 java 代码,这也是我的 oracle objects


CREATE OR REPLACE TYPE "KEY_VALUE_ENTRY"  AS
OBJECT (
  key VARCHAR2(32),
  val VARCHAR2(2048)
);


CREATE OR REPLACE TYPE "KEY_VALUE_MAP"    AS
TABLE OF key_value_entry;

和我的程序

PROCEDURE register_request_(p_request_id IN varchar2
                             ,p_params     IN key_value_map) AS
  BEGIN
    IF p_params IS NOT NULL THEN
      INSERT INTO test_table
        (request, NAME, VALUE)
        SELECT test_seq.nextval
              ,t.key
              ,t.val
          FROM TABLE(CAST(p_params AS key_value_map)) t;
      COMMIT;
  END IF;
  EXCEPTION
    WHEN OTHERS THEN
      RAISE;
  END;

我在 oracle 端使用 3 个 KEY_VALUE_ENTRY 类型的对象,但该对象的 keyval 字段均为空。我不知道我做错了什么。

【问题讨论】:

  • 升级前是否按预期工作?只是检查,因为我不知道它是否有?
  • 是的,它在更新之前工作,但代码略有不同,在这个版本的 ojdbc 上不推荐使用 STRUCT 、 ARRAY 和 ArrayDescriptor 等类
  • 您可能需要重写很多,然后我会怀疑,我要做的是将代码恢复到其工作形式,然后在调试时逐步替换每个部分。所以进行更改调试 进行更改调试。这有点乏味,但我认为您可以找到问题所在
  • 这是我能找到的最好的,但我仍然认为它不能回答你的问题。 stackoverflow.com/questions/37160300/…
  • 这正是我想要做的,但由于某种原因它不起作用stackoverflow.com/questions/19888520/…

标签: java oracle12c


【解决方案1】:

我尝试了这段代码,它按预期工作,无需将 orai18n.jar 添加到类路径。我保持 db 方法不变。

public void insertTable(List<KeyValueObj> list, Connection conn)
            throws SQLException {
        String str = "{call Test_schema.Test_pkg.Register_Request(?,?)}";
        OracleCallableStatement statement = null;
        OracleConnection oraConn = null;
        String requestId = "111";
        try{
            oraConn = conn.unwrap(OracleConnection.class);
            statement = (OracleCallableStatement) oraConn.prepareCall(str);
            statement.setObject(2, getOracleRowObjectList(list, oraConn));
            statement.setString(1,requestId);
            statement.execute();
        }finally {
            try {
                statement.close();
                } catch (Exception e) {

            }
        }

    }

     private Array getOracleRowObjectList(List<KeyValueObj> list, OracleConnection conn) throws SQLException{
        String type = "Test_schema.KEY_VALUE_MAP";
        Struct[] structList = new Struct[list.size()];

        for(int i=0;i<list.size();i++){
            structList[i] = getOracleRowObject(conn, list.get(i));
        }

        return conn.createOracleArray(type, structList);
    }


    private Struct getOracleRowObject(OracleConnection conn, KeyValueObj obj) throws SQLException{
        String typeRow = "Test_schema.KEY_VALUE_ENTRY";
        return conn.createStruct(typeRow,
                new Object[]{ obj.getKey(),
                              obj.getValue(),

        });
    }

KeyValueObj 类

public class KeyValueObj {
    private String key;
    private String value;

    public KeyValueObj(String key, String value) {
        super();
        this.key = key;
        this.value = value;
    }

    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }   

}

希望,这会帮助面临同样问题的人。

【讨论】:

    【解决方案2】:

    在我的classpath 中添加orai18n.jar 后,java 给出了java 给出的值,oracle 取了这个值,一切正常

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-08
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      • 1970-01-01
      • 2011-07-19
      • 2012-11-24
      相关资源
      最近更新 更多