通过SQL语句"select * from"从Java存储过程中返回结果集。

5

我能否通过SQL语句select * from直接获得Java存储过程(Oracle)的结果?

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

因此,Java存储过程应该像一个表一样运行。
在MySQL中,以下操作是可行的(但不适用于Java存储过程):SELECT col1 FROM (EXEC proc1)

在Oracle中是否可能实现这一点,其中proc1为Java存储过程?

5个回答

9

这个答案在另一个论坛上可能会对您有所帮助。

查看消息底部的示例,了解如何从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) 在数据库上创建一个Java类,该类具有静态方法(GetSampleResult),该方法返回一个集合

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) 创建包装器以在函数中使用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>

0
编写一个SSP (SQL存储过程)来调用JSP (Java存储过程),然后在查询中使用该SSP。简单吧。
此外,请查看CallableStatement

你的意思是我可以使用像“select proc() from dual”这样的查询吗? - Ruben S.
不完全是。你看过 CallableStatement 吗,http://download.oracle.com/javase/6/docs/api/java/sql/CallableStatement.html? - Adeel Ansari
@Ruben S:如果 SQL 过程是一个返回集合的函数,你可以执行 select * from function() - user330315
我认为Adeel假设你想使用Java从外部调用那个函数或过程(我之前也这样认为,但现在我想我知道你的意图了)。答案是(我认为)除非您将Java存储过程封装到管道化的PL / SQL函数中,否则无法这样做,然后如果您愿意,可以从sqlplus中执行“select * from table(mywrapper())”。或者您可以从函数返回嵌套表以获得相同的语法... - Samuel

0

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

请查看这里或使用Google/Bing了解更多信息。


0

很抱歉,这是不可能的。但如果您的数据库支持从存储过程中选择数据的功能,您可以创建一个视图并从中选择。

无论如何,Oracle可以从存储过程返回结果集,并且您可以从Java中访问它。请参见此链接


-1

1
他在那里提到的是DB结构的光标。有一种使用集合的方法可以不使用光标来完成它。我刚刚发布了它。 - Alessandro Rossi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接