2017-06-29 86 views
0

ストアドプロシージャからカーソルオブジェクトを返す必要がありますが、データを最初に処理する必要があります。ORACLE - ストアドプロシージャからカーソルを返す

たとえば、のは、この単純なストアドプロシージャを考えてみましょう:

create or replace PROCEDURE TEST 
(
    query_str IN VARCHAR2, 
    CURSOR_ OUT SYS_REFCURSOR 
) 
AS 
BEGIN 
    OPEN CURSOR_ FOR query_str; 
END; 

であるとして、この手順はありません後処理で、データを返します。 私が必要とする改善は以下の通りです:

  1. query_strの実行から来るプロセスデータ。
  2. 処理されたデータをカーソルの形で返します。

誰でも私にこれを達成する方法を提案できますか?

おかげ

+0

処理のどのようなあなたがする必要がある、そしてなぜそれがクエリの一部として行うことができないん参照カーソルを定義するために使用されますか? – Boneist

答えて

1

あなたが、動的SQL(あなたはすべてのプロシージャに渡しているすべての文が同様の出力形式を持っていない限り)で示唆されているものを行うことは困難です。あなたはSELECTが、その後どうなるかを知ることができれば、あなたはそれをコレクションにそれを格納し、処理することができます。

CREATE TABLE TEST_DATA (id, name, dt) AS 
    SELECT 1, 'A', SYSDATE FROM DUAL UNION ALL 
    SELECT 2, 'B', DATE '2017-01-01' FROM DUAL; 

CREATE TYPE processed_data_obj AS OBJECT(
    id INTEGER, 
    etag VARCHAR2(20) 
); 
/

CREATE OR REPLACE TYPE processed_data_table AS TABLE OF processed_data_obj; 
/

CREATE OR REPLACE PROCEDURE TEST 
(
    CURSOR_ OUT SYS_REFCURSOR 
) 
AS 
    processed PROCESSED_DATA_TABLE; 
BEGIN 
    -- Process it in the select statement 
    SELECT processed_data_obj(
      id, 
      name || '_' || ROUND((dt - DATE '1970-01-01') * 24*60*60) 
     ) 
    BULK COLLECT INTO processed 
    FROM test_data; 

    -- Process it more in PL/SQL 
    FOR i IN 1 .. processed.COUNT LOOP 
    processed[i].etag := processed[i].etag || '_' || i; 
    END LOOP; 

    OPEN cursor_out FOR 
    SELECT * 
    FROM TABLE(processed); 
END; 
/
+0

ちょうど質問です。私はストアドプロシージャを書くためにSqlDeveloperを使用しています。 SQLワークシート(クエリーを書くことができるシート)に書いても問題ありません。しかし、私が手順を実行した後、私がそれを開くと、私は "CREATE OR REPLACE PROCEDURE TEST ..."から始まるコードしか見つけられません。どこの文を書くことができますか(CREATE TYPE、...)?したがって、Javaアプリケーションからストアを呼び出すと、すべてのステートメントを実行できるようになります – Fab

+0

@Fab CREATE TYPEステートメントはOracleのデータ・ディクショナリに格納されています。プロシージャに使用するのと同じ方法を使用してSQL Developerで見つけることができます; 'Procedures'フォルダではなく' Connections'タブの 'Types'サブフォルダを展開すれば、そこにリストされます。ただし、型を作成した後は永遠に存在するため、プロシージャを呼び出すたびに再作成する必要はありません。 – MT0

+0

プロシージャとタイプの両方が作成されています。しかし、問題はもう一つです。 Javaを使って 'call TEST(?)'でプロシージャを呼び出すつもりです。私は 'CREATE PROCEDURE'コードだけが実行されると思います。したがって、可能性は2です:私の型は既に利用可能です。または....プロシージャを呼び出すときに 'CREATE'ステートメントを実行する方法はありますか? – Fab

関連する問題