无法访问存储过程的 OUT 参数
Unable to access stored procedure's OUT parameter
我们正在尝试通过 Toplink 使用 Java 代码中的存储过程,但我们似乎遇到了一个问题,我一直无法找到答案。可能是我的 Google-Fu 在这种情况下让我失望了。
我们的问题是,虽然程序似乎被正确调用,但我们没有返回到 Java 代码。所讨论的过程已通过 SQLDeveloper 使用相同的输入参数和过程 returns 应有的值进行了测试。
程序签名为
create or replace PACKAGE FORM_METADATA AS
PROCEDURE FORM_LIST_GET (
P_USER_ID IN VARCHAR2,
P_CHANNEL_NO IN NUMBER,
P_START_FROM IN NUMBER, --pagination
P_COUNT_TO_RETURN IN NUMBER, --pagination
P_GET_TOTAL_COUNT IN NUMBER, -- if total count should be returned then 1, other wise 0
P_RESULT_SET OUT SYS_REFCURSOR,
P_TOTAL_COUNT OUT NUMBER);
end FORM_METADATA;
调用此过程的 Java 代码如下所示:
BigDecimal 计数 = new BigDecimal(-1);
Session session = getSession();
session.setLog(new OutputStreamWriter(System.out));
session.setLogLevel(SessionLog.FINEST);
StoredProcedureCall procedureCall = new StoredProcedureCall();
procedureCall.setProcedureName("FORM_METADATA.FORM_LIST_GET");
procedureCall.addNamedArgumentValue("P_USER_ID", "UserID-1");
procedureCall.addNamedArgumentValue("P_CHANNEL_NO", new BigDecimal(1));
procedureCall.addNamedArgumentValue("P_START_FROM", new BigDecimal(1));
procedureCall.addNamedArgumentValue("P_COUNT_TO_RETURN", new BigDecimal(1000));
procedureCall.addNamedArgumentValue("P_GET_TOTAL_COUNT", new BigDecimal(1));
procedureCall.useNamedCursorOutputAsResultSet("P_RESULT_SET");
procedureCall.addNamedOutputArgument("P_TOTAL_COUNT", "count", BigDecimal.class);
DataReadQuery dq = new DataReadQuery();
dq.setCall(procedureCall);
dq.prepareForExecution();
Object result = session.executeQuery(dq);
System.out.println("Result:: " + result);
System.out.println("Result from StoredProcedreCall: " + procedureCall.getResult());
我们收到的输出如下所示:
[TopLink Warning]: 2015.08.31 16:11:30.781--Failed to get InitialContext for MBean registration: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
[TopLink Warning]: 2015.08.31 16:11:30.797--Failed to get InitialContext for MBean registration: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
[TopLink Info]: 2015.08.31 16:11:31.685--DatabaseSessionImpl(1827000661)--TopLink, version: Oracle TopLink - 11g Release 1 (11.1.1.5.0) (Build 110305)
[TopLink Info]: 2015.08.31 16:11:34.147--DatabaseSessionImpl(1827000661)--dev login successful
[TopLink Finest]: 2015.08.31 16:11:34.147--DatabaseSessionImpl(1827000661)--Thread(Thread[main,5,main])--Execute query DataReadQuery()
[TopLink Finest]: 2015.08.31 16:11:34.163--DatabaseSessionImpl(1827000661)--Thread(Thread[main,5,main])--reconnecting to external connection pool
[TopLink Fine]: 2015.08.31 16:11:34.227--DatabaseSessionImpl(1827000661)--Connection(1635575430)--Thread(Thread[main,5,main])--BEGIN FORM_METADATA.FORM_LIST_GET(P_USER_ID=>?, P_CHANNEL_NO=>?, P_START_FROM=>?, P_COUNT_TO_RETURN=>?, P_GET_TOTAL_COUNT=>?, P_RESULT_SET=>?, P_TOTAL_COUNT=>?); END;
bind => [UserID-1, 1, 1, 1000, 1, => P_RESULT_SET, => P_TOTAL_COUNT]
Result:: []
Result from StoredProcedreCall: null
Process exited with exit code 0.
我相当确定我们的问题出在调用过程的 Java 代码上,但正如我所说,我们还没有找到正确的解决方案。谁能告诉我们接下来应该从哪里开始寻找?
提前谢谢你,
米卡
更新:
我的一位同事设法找到了该程序似乎没有 return 任何东西的原因。为了简洁起见,我编辑了几个参数,我们在这个例子中没有使用它们,我们认为它们不是感知行为的原因。但是,由于参数是强制性的,因此这些参数被设置为 NULL。我的同事想尝试初始化没有值的参数,然后查询 returned 了一组预期的数据。
所以我们的代码更改(在 Java 中)是从
procedureCall.addNamedArgumentValue("P_ORDER_BY", OracleTypes.NULL);
至
procedureCall.addNamedArgument("P_ORDER_BY");
现在我们按预期从游标中获取了数据,但是第二个 out 参数的值仍然无法获取。
在更集中地搜索访问第二个输出参数后,我们在 Oracle 的论坛中找到了 this thread,这导致了我们需要的解决方案。
我们正在尝试通过 Toplink 使用 Java 代码中的存储过程,但我们似乎遇到了一个问题,我一直无法找到答案。可能是我的 Google-Fu 在这种情况下让我失望了。
我们的问题是,虽然程序似乎被正确调用,但我们没有返回到 Java 代码。所讨论的过程已通过 SQLDeveloper 使用相同的输入参数和过程 returns 应有的值进行了测试。
程序签名为
create or replace PACKAGE FORM_METADATA AS
PROCEDURE FORM_LIST_GET (
P_USER_ID IN VARCHAR2,
P_CHANNEL_NO IN NUMBER,
P_START_FROM IN NUMBER, --pagination
P_COUNT_TO_RETURN IN NUMBER, --pagination
P_GET_TOTAL_COUNT IN NUMBER, -- if total count should be returned then 1, other wise 0
P_RESULT_SET OUT SYS_REFCURSOR,
P_TOTAL_COUNT OUT NUMBER);
end FORM_METADATA;
调用此过程的 Java 代码如下所示: BigDecimal 计数 = new BigDecimal(-1);
Session session = getSession();
session.setLog(new OutputStreamWriter(System.out));
session.setLogLevel(SessionLog.FINEST);
StoredProcedureCall procedureCall = new StoredProcedureCall();
procedureCall.setProcedureName("FORM_METADATA.FORM_LIST_GET");
procedureCall.addNamedArgumentValue("P_USER_ID", "UserID-1");
procedureCall.addNamedArgumentValue("P_CHANNEL_NO", new BigDecimal(1));
procedureCall.addNamedArgumentValue("P_START_FROM", new BigDecimal(1));
procedureCall.addNamedArgumentValue("P_COUNT_TO_RETURN", new BigDecimal(1000));
procedureCall.addNamedArgumentValue("P_GET_TOTAL_COUNT", new BigDecimal(1));
procedureCall.useNamedCursorOutputAsResultSet("P_RESULT_SET");
procedureCall.addNamedOutputArgument("P_TOTAL_COUNT", "count", BigDecimal.class);
DataReadQuery dq = new DataReadQuery();
dq.setCall(procedureCall);
dq.prepareForExecution();
Object result = session.executeQuery(dq);
System.out.println("Result:: " + result);
System.out.println("Result from StoredProcedreCall: " + procedureCall.getResult());
我们收到的输出如下所示:
[TopLink Warning]: 2015.08.31 16:11:30.781--Failed to get InitialContext for MBean registration: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
[TopLink Warning]: 2015.08.31 16:11:30.797--Failed to get InitialContext for MBean registration: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
[TopLink Info]: 2015.08.31 16:11:31.685--DatabaseSessionImpl(1827000661)--TopLink, version: Oracle TopLink - 11g Release 1 (11.1.1.5.0) (Build 110305)
[TopLink Info]: 2015.08.31 16:11:34.147--DatabaseSessionImpl(1827000661)--dev login successful
[TopLink Finest]: 2015.08.31 16:11:34.147--DatabaseSessionImpl(1827000661)--Thread(Thread[main,5,main])--Execute query DataReadQuery()
[TopLink Finest]: 2015.08.31 16:11:34.163--DatabaseSessionImpl(1827000661)--Thread(Thread[main,5,main])--reconnecting to external connection pool
[TopLink Fine]: 2015.08.31 16:11:34.227--DatabaseSessionImpl(1827000661)--Connection(1635575430)--Thread(Thread[main,5,main])--BEGIN FORM_METADATA.FORM_LIST_GET(P_USER_ID=>?, P_CHANNEL_NO=>?, P_START_FROM=>?, P_COUNT_TO_RETURN=>?, P_GET_TOTAL_COUNT=>?, P_RESULT_SET=>?, P_TOTAL_COUNT=>?); END;
bind => [UserID-1, 1, 1, 1000, 1, => P_RESULT_SET, => P_TOTAL_COUNT]
Result:: []
Result from StoredProcedreCall: null
Process exited with exit code 0.
我相当确定我们的问题出在调用过程的 Java 代码上,但正如我所说,我们还没有找到正确的解决方案。谁能告诉我们接下来应该从哪里开始寻找?
提前谢谢你,
米卡
更新:
我的一位同事设法找到了该程序似乎没有 return 任何东西的原因。为了简洁起见,我编辑了几个参数,我们在这个例子中没有使用它们,我们认为它们不是感知行为的原因。但是,由于参数是强制性的,因此这些参数被设置为 NULL。我的同事想尝试初始化没有值的参数,然后查询 returned 了一组预期的数据。
所以我们的代码更改(在 Java 中)是从
procedureCall.addNamedArgumentValue("P_ORDER_BY", OracleTypes.NULL);
至
procedureCall.addNamedArgument("P_ORDER_BY");
现在我们按预期从游标中获取了数据,但是第二个 out 参数的值仍然无法获取。
在更集中地搜索访问第二个输出参数后,我们在 Oracle 的论坛中找到了 this thread,这导致了我们需要的解决方案。