如何从Java调用的流水线函数中捕获PL/SQL错误

如何从Java调用的流水线函数中捕获PL/SQL错误,java,oracle,plsql,ojdbc,Java,Oracle,Plsql,Ojdbc,在基于Oracle(11g)的应用程序中,我们大量使用流水线函数。现在证明,从这些函数报告错误是困难的,如下面的(缩减)示例所示。 该过程是为了从Java调用而存在的,它将在PL/SQL执行过程中的任何地方接收错误 甲骨文部分: 运行上述函数会导致显示异常: ORA-00904:“列错误”:列名无效 Java部分: 异常将不会被捕获。结果集为空 这是预期的行为吗?我们做错什么了吗?是否存在解决方法?问题是您正在提出未找到任何数据,而栏中的光标未将其视为例外情况选择(您打开的光标有效)不返回任

在基于Oracle(11g)的应用程序中,我们大量使用流水线函数。现在证明,从这些函数报告错误是困难的,如下面的(缩减)示例所示。 该过程是为了从Java调用而存在的,它将在PL/SQL执行过程中的任何地方接收错误

甲骨文部分:

运行上述函数会导致显示异常:

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