1

我正在尝试将 sql.Array 发送到过程中,但不知何故它在 oracle 过程中变空了。

我的 java 代码用数据填充 sql.Array 并尝试将其发送到过程中。

         oracle.jdbc.OracleConnection connection = (OracleConnection) JdbcConnection.getInstance().createConnection();
            String [] name = new String[]{"20206643799002684001","20206643799002684001"};
            ArrayDescriptor arrDec = ArrayDescriptor.createDescriptor("ARRAY_VARCHAR2",connection.unwrap(oracle.jdbc.OracleConnection.class));
            Array arr = new ARRAY(arrDec,connection.unwrap(oracle.jdbc.OracleConnection.class),name);
            OracleCallableStatement callableStatement = connection.prepareCall("{call bss_acc.ACC_STATEMENT(?,?,?,?)}");
            callableStatement.setDate(1,date);
            callableStatement.setDate(2,dateL);
           ((OracleCallableStatement)callableStatement).setARRAY(3,arr);
            callableStatement.setString(4,this.branchId);
            callableStatement.execute();

在程序中,我输入日志以查看执行此程序后得到的值。而且我总是得到空数组元素,它出现在这个过程中。

procedure ACC_STATEMENT
(
i_begin_date date,
i_end_date date,
i_ids array_varchar2,
i_mfo varchar2
)
is
o_ext_acc varchar2(20);
o_beginRest number;
o_endRest number;
o_name varchar2(100);
o_rest number;
o_type varchar2(100);

begin

FOR i IN 1.. i_ids.count LOOP
o_ext_acc := i_ids(i);

-- test

RAISE_ERROR(20000, 'o_ext_acc -' ||o_ext_acc);

我看到在使用空 o_ext_acc 执行此错误以显示此消息后,我将其重定向到其他过程

java.sql.SQLException: ORA-20000: 
20000:  o_ext_acc -
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447)
  at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
  at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:951)
  at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:513)
  at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:227)
  at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
  at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:205)
  at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:1043)
  at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1336)
  at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3613)
  at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3714)
  at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4755)
  at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1378)
  at com.uzb.bank.demo.service.impl.GenerateIntoXmlImpl.accountStatement(GenerateIntoXmlImpl.java:414)
  at com.uzb.bank.demo.controller.Controller.accountStatement(Controller.java:72)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
  at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
  at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
  at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
  at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
  at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
  at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
  at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
  at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
  at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
  at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)

UPD 当我设置调试模式以查看 arr 发生了什么时,我注意到了这个数据。这意味着数组不会从中获取值,而是显示问号而不是它。

在此处输入图像描述

UPD

我知道我正在使用 sql 数组并将其更改为 oracle.sql.Array 并尝试使用以下代码创建,但它再次运行为空。

 oracle.jdbc.OracleConnection connection = (OracleConnection) JdbcConnection.getInstance().createConnection();
            String [] name = new String[]{"20206643799002684001","20206643799002684001"};
            oracle.sql.ARRAY a = connection.createARRAY("ARRAY_VARCHAR2",name);
            CallableStatement callableStatement = connection.prepareCall("{call bss_acc.ACC_STATEMENT(?,?,?,?)}");
            callableStatement.setDate(1,date);
            callableStatement.setDate(2,dateL);
           ((OracleCallableStatement)callableStatement).setArray(3,a);
            callableStatement.setString(4,this.branchId);
            callableStatement.execute();

更新 3

        oracle.jdbc.OracleConnection connection = (OracleConnection) JdbcConnection.getInstance().createConnection();
        String [] name = new String[]{"20206643799002684001","20206643799002684001"};
        oracle.sql.ArrayDescriptor arrayDescriptor = new ArrayDescriptor("ARRAY_VARCHAR2",connection);
        oracle.sql.ARRAY a = new ARRAY(arrayDescriptor,connection,name);
        OracleCallableStatement callableStatement = (OracleCallableStatement) connection.prepareCall("{call bss_acc.ACC_STATEMENT(?,?,?,?)}");
        callableStatement.setDate(1,date);
        callableStatement.setDate(2,dateL);
        callableStatement.setARRAY(3,a);
        callableStatement.setString(4,this.branchId);
        callableStatement.execute();

更新 4

发送空的 oracle.sql.Array 后,它从我的过程中给出错误并打印部分显示空的 sql 数组元素

java.sql.SQLException: ORA-20000:

20000: o_ext_acc:/ empty 此处发送数组元素为空。这里应该是发送数组/ORA-06512 的元素: - “IBS.RAISE_ERROR”,第 74 行 ORA-06512: - “IBS.BSS_ACC”,第 30 行 ORA-06512: - 第 1 行

在 oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447) 在 oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396) 在 oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:951 ) 在 oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:513)

更新 5

我修改它的程序

FOR i IN 1.. i_ids.count LOOP o_ext_acc := i_ids(i);

-- test

RAISE_ERROR(20000, 'date:' || i_begin_date || 'accountElement ' || o_ext_acc);

然后我得到以下错误,我可以看到日期但 有空的 o_ext_acc

java.sql.SQLException:ORA-20000:20000:日期:02.09.19accountElement

我无法捕获在过程中发送 oracle.jdbc.Array 的问题,它以某种方式从 jdbc 进入 oracle 过程,如空数组并且元素为空

我从 Oracle 运行这个程序,它工作正常,没有错误

4

2 回答 2

0

使用oracle.sql.ARRAYandoracleConnection.setARRAY()而不是java.sql.Arrayand javaConnection.setArray()

Connection connection = JdbcConnection.getInstance().createConnection();
OracleConnection oconnection = (OracleConnection) connection.unwrap( oracle.jdbc.OracleConnection.class );

String [] name = new String[]{"20206643799002684001","20206643799002684001"};
ArrayDescriptor arrDec = ArrayDescriptor.createDescriptor("ARRAY_VARCHAR2",oconnection);
ARRAY arr = new ARRAY(arrDec,oconnection,name);
/*
 * Or
 * ARRAY arr = oconnection.createARRAY("ARRAY_VARCHAR2", name);
 */
OracleCallableStatement callableStatement
  = (OracleCallableStatement) oconnection.prepareCall("{call bss_acc.ACC_STATEMENT(?,?,?,?)}");
callableStatement.setDate(1,date);
callableStatement.setDate(2,dateL);
callableStatement.setARRAY(3,arr);
callableStatement.setString(4,this.branchId);
callableStatement.execute();

另请参阅:我对“在 Java 中插入 Oracle 嵌套表”的回答

于 2019-09-09T08:30:38.000 回答
0

经过两天的搜索主要问题是 datumnArray 是???。这意味着 oracld db 和 jdbc 与其字符集不匹配。添加此代码后。

 String s1 = new String(account.get(0).getBytes(), Charset.forName("ISO-8859-1"));
                String [] name = new String[]{s1};
                //oracle.sql.ArrayDescriptor arrayDescriptor = new ArrayDescriptor("ARRAY_VARCHAR2",connection);
                oracle.sql.ARRAY a = connection.createARRAY("ARRAY_VARCHAR2", name);

在此处输入图像描述

并将此库添加到 maven

<dependency>
        <groupId>com.oracle</groupId>
        <artifactId>orai18n</artifactId>
        <version>11.1.0.7.0</version>
    </dependency>

这对我有用。我认为他们两个都是解决问题的关键。开头是下图。

在此处输入图像描述

于 2019-09-09T11:51:28.577 回答