【问题标题】:returning a result set from a java stored procedure through SQL "select * from "通过 SQL“select * from”从 java 存储过程返回结果集
【发布时间】:2011-08-10 02:07:45
【问题描述】:

我可以直接通过 SQL select * from 语句从 java 存储过程 (oracle) 获取结果吗?

在数据库上,我会有一个 java 存储过程/函数,当它调用它时会返回一个多列、多行的结果集。
我想通过select * from [table] 语句直接访问这些结果。

所以 java 存储过程应该表现得像一个表。
在 MySQL 中,以下内容应该是可能的(但不是 java 存储过程):SELECT col1 FROM (EXEC proc1)

在 proc1 是 java 存储过程的 oracle 中这可能吗?

【问题讨论】:

    标签: java sql oracle stored-procedures


    【解决方案1】:

    其他论坛上的This answer 可能会对您有所帮助。

    查看消息底部的示例,了解如何从 Java 方法(也可能是 Java 存储过程)返回的集合中进行选择。

    这是一个关于如何使用 Java 存储过程的示例

    1) 创建DB对象来定义返回行的类型:

    create type try_obj as object (
            field_a number,
            field_b varchar2(10)
        )
    /
    
    create type try_obj_tab as table of try_obj
    /
    

    2) 使用返回 Collection 的静态方法 (GetSampleResult) 在 DB 上创建 Java 类

    create or replace and compile java source named QueryReturn as
    import java.sql.*;
    import java.util.*;
    
    import oracle.jdbc.*;
    import oracle.jdbc.pool.OracleDataSource;
    import oracle.sql.*;
    
    
    public class QueryReturn implements ORADataFactory,ORAData{
        private NUMBER field1;
        private CHAR field2;
    
        public QueryReturn(OracleConnection conn,int n,String c) throws SQLException {
            field1 = new NUMBER(n);
            field2 = new CHAR(c,oracle.sql.CharacterSet.make(conn.getStructAttrCsId()));
        }
    
        public QueryReturn(NUMBER n, CHAR c) {
            field1 = n;
            field2 = c;
        }
        public QueryReturn(Object[] attributes) {
            this(
                    (NUMBER) attributes[0],
                    (CHAR) attributes[1]
                );
        }
        public QueryReturn(Datum d) throws SQLException {
            this(((STRUCT) d).getOracleAttributes());
        }
    
        public ORAData create(Datum d, int sqlType) throws SQLException {
            if (d == null)
                return null;
            else {
                return new QueryReturn(d);
            }
        }
    
        public STRUCT toSTRUCT(Connection conn) throws SQLException  {
            StructDescriptor sd =
                StructDescriptor.createDescriptor("TRY_OBJ", conn);
            Object [] attributes = { field1,field2 };
            return new STRUCT(sd, conn, attributes);
        }
        public Datum toDatum(Connection conn) throws SQLException {
            return toSTRUCT(conn); 
        }
    
    
        public static ARRAY GetSampleResult() throws SQLException, ClassNotFoundException {
            // initialize the connection
            OracleConnection conn = null;
            conn = (OracleConnection) (new oracle.jdbc.OracleDriver()).defaultConnection();
    
            // create the return java array
            // There will be two Rows
            //  1   abc
            //  2   dce
            QueryReturn javaArray[] = {
                    new QueryReturn(conn,1,"abc"),
                    new QueryReturn(conn,2,"dce")
                };
    
            // Map the java class to the Oracle type
            Map map = conn.getTypeMap();
            map.put("TRY_OBJ", Class.forName("QueryReturn"));
            ArrayDescriptor jTryObjArrayDesc = ArrayDescriptor.createDescriptor (
                    "TRY_OBJ_TAB",
                    conn
                );
    
    
            // create an Oracle collection on client side to use as parameter
            ARRAY oracleCollection = new ARRAY(jTryObjArrayDesc,conn,javaArray);
    
            return oracleCollection;
        }
    }
    

    3) 创建 Wrap 以在函数中使用 Java 存储过程

    create or replace function GetSampleResult 
        return try_obj_tab
    AS LANGUAGE JAVA
        NAME  'QueryReturn.GetSampleResult()  return oracle.sql.ARRAY';
    

    4) 显示结果

    SQL> select *
      2  from table(GetSampleResult())
      3  /
    
       FIELD_A FIELD_B
    ---------- ----------
             1 abc
             2 dce
    
    SQL>
    

    【讨论】:

      【解决方案2】:

      编写一个 SSP(SQL 存储过程)来调用 JSP(Java 存储过程),然后在查询中使用该 SSP。简单啊。

      进一步,看看CallableStatement

      【讨论】:

      • 你的意思是我可以使用诸如“select proc() from dual”之类的查询?
      • 不完全是。你看过 CallableStatement,download.oracle.com/javase/6/docs/api/java/sql/… 吗?
      • @Ruben S:如果 SQL 过程是一个集合返回函数,你可以这样做select * from function()
      • 我认为 Adeel 假设您想使用 Java 从外部调用该函数或过程(我也假设了,但现在我想我知道您要去哪里了)。答案是(我认为)你不能,除非你将 Java SP 包装到流水线化的 PL/SQL 函数中,然后如果你愿意,你可以从 sqlplus 中执行“select * from table(mywrapper())”。或者你可以从你的函数返回一个嵌套表,语法相同......
      【解决方案3】:

      我从未将它与调用存储过程的 Java 结合使用,但我猜应该可以在最近的 Oracle 数据库中使用“流水线”功能。

      请参阅here 或 Google/Bing 以了解更多信息。

      【讨论】:

        【解决方案4】:

        恐怕这是不可能的。但是,如果您的数据库支持以您提到的方式从存储过程中选择数据的功能,您可以创建一个视图并从中进行选择。

        无论如何,Oracle 可以从存储过程返回结果集,并且您可以从 Java 访问它。见this link

        【讨论】:

          【解决方案5】:

          【讨论】:

          • 他指的是作为数据库结构的游标。有一种方法,使用集合,不使用游标就可以做到。刚刚发布了
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-03-27
          • 1970-01-01
          • 1970-01-01
          • 2011-03-20
          • 2023-04-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多