如何从Java调用的流水线函数中捕获PL/SQL错误
在基于Oracle(11g)的应用程序中,我们大量使用流水线函数。现在证明,从这些函数报告错误是困难的,如下面的(缩减)示例所示。 该过程是为了从Java调用而存在的,它将在PL/SQL执行过程中的任何地方接收错误 甲骨文部分: 运行上述函数会导致显示异常:如何从Java调用的流水线函数中捕获PL/SQL错误,java,oracle,plsql,ojdbc,Java,Oracle,Plsql,Ojdbc,在基于Oracle(11g)的应用程序中,我们大量使用流水线函数。现在证明,从这些函数报告错误是困难的,如下面的(缩减)示例所示。 该过程是为了从Java调用而存在的,它将在PL/SQL执行过程中的任何地方接收错误 甲骨文部分: 运行上述函数会导致显示异常: ORA-00904:“列错误”:列名无效 Java部分: 异常将不会被捕获。结果集为空 这是预期的行为吗?我们做错什么了吗?是否存在解决方法?问题是您正在提出未找到任何数据,而栏中的光标未将其视为例外情况选择(您打开的光标有效)不返回任
ORA-00904:“列错误”:列名无效
Java部分:
异常将不会被捕获。结果集为空
这是预期的行为吗?我们做错什么了吗?是否存在解决方法?问题是您正在提出
未找到任何数据,而栏中的光标未将其视为例外情况选择(您打开的光标有效)不返回任何行是有效的。当您运行匿名块时,您只看到dbms\u输出
调用,而没有引发异常-块成功完成,如果关闭serveroutput
,您将看不到任何内容。(编辑:)
不清楚为什么在捕获异常类型后要尝试更改它。我认为这样做的唯一原因是获得您的行为,其中任何错误都会给您一个空的结果集,而不是您必须处理的异常。如果这不是你想发生的事情,那么你就不应该这样做,把显而易见的事情说出来。如果是,那么您需要从Java端查找dbms\u输出
消息
但我不明白为什么您希望这样做,而只是重新调用原始异常:
when others then
dbms_output.put_line(SQLCODE||' '||sqlerrm );
raise;
。。。或者,由于dbms\u输出
并不总是对客户端可见,只是根本不捕获其他
。当您希望(Java)客户端看到异常时,捕获并挤压异常似乎有点毫无意义,而且违反直觉
Java端的异常将类似于(从e.getMessage()
):
也许您想隐藏PL/SQL堆栈跟踪,只显示遇到的第一个错误的一行,但似乎保留该信息以便跟踪错误更有用
package test1;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import oracle.jdbc.OracleTypes;
public class start {
public static void main(String[] args)
{
try
{
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@...", "…", "…");
CallableStatement stmt = con.prepareCall("BEGIN mytest.bar(?); END;");
stmt.registerOutParameter(1, OracleTypes.CURSOR);
stmt.executeQuery();
ResultSet rs = (ResultSet)stmt.getObject(1);
while (rs.next())
{
System.out.println(rs.getInt(1));
}
stmt.close();
con.close();
} catch (Exception e)
{
e.printStackTrace();
}
}
}
when others then
dbms_output.put_line(SQLCODE||' '||sqlerrm );
raise;
ORA-00904: "WRONG_COLUMN": invalid identifier
ORA-06512: at "SCHEMA.MYTEST", line 23