возврат результирующего набора из хранимой процедуры java через SQL «select * from»

#java #sql #oracle #stored-procedures

#java #sql #Oracle #хранимые процедуры

Вопрос:

Могу ли я получить результат из хранимой процедуры Java (oracle) непосредственно с помощью инструкции SQL select * from ?

В базе данных у меня была бы хранимая процедура / функция Java, которая при вызове возвращает результирующий набор из нескольких столбцов и нескольких строк.
Я хотел бы получить доступ к этим результатам напрямую через select * from [table] инструкцию.

Таким образом, хранимая процедура Java должна вести себя как таблица.
В MySQL должно быть возможно следующее (но не хранимые процедуры Java): SELECT col1 FROM (EXEC proc1)

Возможно ли это в oracle, где proc1 является хранимой процедурой Java?

Ответ №1:

Этот ответ на другом форуме может вам помочь.

Посмотрите на пример в нижней части сообщения, чтобы увидеть, как выбрать из коллекции, возвращаемой методом 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>
  

Ответ №2:

Напишите SSP (хранимую процедуру SQL) для вызова JSP (хранимая процедура Java), а затем используйте этот SSP в своем запросе. Просто, да.

Далее, взгляните на CallableStatement .

Комментарии:

1. Вы имеете в виду, что я мог бы затем использовать запросы типа «select proc() from dual»?

2. Не совсем. Вы смотрели CallableStatement, download.oracle.com/javase/6/docs/api/java/sql /… ?

3. @Ruben S: Если процедура SQL является функцией возврата набора, вы можете сделать select * from function()

4. Я думаю, Adeel предполагает, что вы хотите вызвать эту функцию или процедуру извне, используя Java (я тоже так предполагал, но теперь, кажется, я понимаю, к чему вы клоните). Ответ таков (я думаю), что вы не можете, если только вы не обернете свой Java SP в конвейерную функцию PL / SQL, и тогда вы могли бы выполнить свой «select * from table (mywrapper())» из sqlplus, если хотите. Или вы могли бы вернуть вложенную таблицу из вашей функции для того же синтаксиса…

Ответ №3:

Я никогда не использовал его в сочетании с Java, вызывающей хранимую процедуру, но я предполагаю, что должна быть возможность использовать «конвейерную» функциональность в последних базах данных Oracle.

Смотрите здесь или Google / Bing, чтобы узнать больше.

Ответ №4:

Боюсь, это невозможно. Но если ваша база данных поддерживает функциональность выбора данных из хранимой процедуры указанным вами способом, вы можете создать представление и выбрать из него.

В любом случае Oracle может вернуть результирующий набор из хранимой процедуры, и вы можете получить к нему доступ из Java. Смотрите эту ссылку

Ответ №5:

Комментарии:

1. Он имел в виду курсоры там, которые являются структурами БД. Существует способ, использующий коллекции, который делает это без использования курсоров. Только что опубликовал это