oracle 通过数据库链接获取 ResultSet/RefCursor

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2549417/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 20:19:39  来源:igfitidea点击:

Getting a ResultSet/RefCursor over a database link

oraclejdbcoracle10gresultsetora-24338

提问by JonathanJ

From the answers to calling a stored proc over a dblinkit seems that it is not possible to call a stored procedure and get the ResultSet/RefCursor back if you are making the SP call across a remote DB link. We are also using Oracle 10g.

通过 dblink调用存储过程的答案来看,如果您通过远程数据库链接进行 SP 调用,似乎不可能调用存储过程并取回 ResultSet/RefCursor。我们也在使用 Oracle 10g。

We can successfully get single value results across the link, and can successfully call the SP and get the results locally but we get the same 'ORA-24338: statement handle not executed' error when reading the ResultSet from the remote DB.

我们可以通过链接成功获取单值结果,并且可以成功调用 SP 并在本地获取结果,但是当从远程 DB 读取 ResultSet 时,我们得到相同的“ORA-24338:语句句柄未执行”错误。

My question - is there any workaround to using the stored procedure? Is a shared view a better solution? Piped rows?

我的问题 - 有没有使用存储过程的解决方法?共享视图是更好的解决方案吗?管道排?

Sample Stored Procedure:

示例存储过程:

CREATE OR REPLACE PACKAGE BODY example_SP
IS

  PROCEDURE get_terminals(p_CD_community   IN  community.CD_community%TYPE,
                          p_cursor         OUT SYS_REFCURSOR)
  IS
  BEGIN
    OPEN p_cursor FOR
    SELECT cd_terminal
    FROM terminal t, community c
    WHERE c.cd_community = p_CD_community
    AND t.id_community = c.id_community;
  END;

END example_SP;
/

Sample Java code that works locally but not remotely:

可在本地运行但不能远程运行的示例 Java 代码:

 Connection conn = DBConnectionManagerFactory.getDBConnectionManager().getConnection();
    CallableStatement cstmt = null;
    ResultSet rs = null;
    String community = "EXAMPLE";

    try
    {
        cstmt = conn.prepareCall("{call example_SP.get_terminals@remote_address(?,?)}");
        cstmt.setString(1, community);
        cstmt.registerOutParameter(2, OracleTypes.CURSOR);

        cstmt.execute();

        rs = (ResultSet)cstmt.getObject(2);

        while (rs.next())
        {
              LogUtil.getLog().logInfo("Terminal code=" + rs.getString( "cd_terminal" ));
        }

    }

采纳答案by Gary Myers

Option 1. Go for a direct connection from Java to the remote database rather than going through the local database. Simpler, but it is up to the application to co-ordinate the two separate transactions. If one database is just used for reads and not writes, I'd go this route.

选项 1. 从 Java 直接连接到远程数据库,而不是通过本地数据库。更简单,但由应用程序来协调两个单独的事务。如果一个数据库只用于读取而不是写入,我会走这条路。

You can use with a straight query or a stored procedure and ref cursor. I'd generally go with the former unless there is a good reason to add in a stored procedure layer.

您可以使用直接查询或存储过程和引用游标。除非有充分的理由添加存储过程层,否则我通常会选择前者。

Option 2. Go for a direct query in the local database using the database link.

选项 2. 使用数据库链接在本地数据库中进行直接查询。

Option 3. As (2), but hide the query in a view (or synonym) stored on the local database.

选项 3. 与 (2) 相同,但将查询隐藏在存储在本地数据库中的视图(或同义词)中。

Option 4. If the result set is small enough, you could have a procedure on the local database call a procedure on the remote database. The remote procedure would return the result as XML or a structured CLOB (eg JSON) which could be 'decoded' by either the local procedure or the java layer.

选项 4。如果结果集足够小,您可以让本地数据库上的过程调用远程数据库上的过程。远程过程会将结果作为 XML 或结构化 CLOB(例如 JSON)返回,这些结果可以由本地过程或 java 层“解码”。