2016-06-24 8 views
1

何をしますか:カスタム関数を使用してカスタム関数を使用してテーブルからデータを取得します。テーブルから関数を介して行を取得する

create table ACCOUNTCONTRACT 
(
    accountcode_   VARCHAR2(255 CHAR), 
    accountmig_    NUMBER(1), 
    accountnumber_   VARCHAR2(25 CHAR) not null, 
    accountpk_    NUMBER(19), 
    addinfo1_    VARCHAR2(255 CHAR), 
    addinfo2_    VARCHAR2(255 CHAR), 
... 

私がやったこと:私のカスタム・タイプを作成

CREATE OR REPLACE TYPE "FO_OUTPUT" AS OBJECT 
(
    NUMCPT  VARCHAR2(10), 
    ACTIONACCOUNT VARCHAR2(50) 
) 

CREATE OR REPLACE TYPE "FO_OUTPUT_TABLE" AS TABLE OF FO_OUTPUT 

My機能は次のとおりです。

私のテーブルの構造は以下のようなものです

CREATE OR REPLACE FUNCTION OUTPUT_FO RETURN FO_OUTPUT_TABLE AS 
    RETVAL FO_OUTPUT_TABLE := FO_OUTPUT_TABLE(); 
    TMPLINE FO_OUTPUT; 
    PRAGMA AUTONOMOUS_TRANSACTION; 
BEGIN 
    FOR I IN (SELECT SUBSTR(ACC.ACCOUNTNUMBER_, 1, 10) AS NUMCPT, 
        ACC.ACCOUNTNUMBER_ AS ACTIONACCOUNT 
       INTO TMPLINE.NUMCPT, TMPLINE.ACTIONACCOUNT 
       FROM ACCOUNTCONTRACT ACC 
      WHERE ROWNUM < 10) LOOP 

    RETVAL.EXTEND; 
    RETVAL(RETVAL.COUNT) := TMPLINE; 
    END LOOP; 
    RETURN(RETVAL); 
END OUTPUT_FO; 

今すぐ実行: `SELECT * FROM TABLE(OUTPUT_FO)私が持っているのは空白行10個です。

私のコードに間違いがあります。 thnx

ここで私はそれが仕事を得るためにやった

答えて

1
CREATE OR REPLACE FUNCTION OUTPUT_FO RETURN FO_OUTPUT_TABLE AS RETVAL FO_OUTPUT_TABLE := FO_OUTPUT_TABLE(); 
TMPLINE FO_OUTPUT; 
PRAGMA AUTONOMOUS_TRANSACTION; 
BEGIN 
    TMPLINE := FO_OUTPUT('', ''); 
    FOR I IN (SELECT SUBSTR(ACC.ACCOUNTNUMBER_, 1, 10) AS NUMCPT, 
        ACC.ACCOUNTNUMBER_ AS ACTIONACCOUNT 
       --INTO TMPLINE.NUMCPT, TMPLINE.ACTIONACCOUNT << this does not work 
       FROM ACCOUNTCONTRACT ACC 
      WHERE ROWNUM < 10) LOOP 

    -- But this:     
    TMPLINE.numcpt:= i.numcpt; 
    TMPLINE.ACTIONACCOUNT:= i.ACTIONACCOUNT; 

    RETVAL.EXTEND; 
    RETVAL(RETVAL.COUNT) := TMPLINE; 
    END LOOP; 
    RETURN(RETVAL); 
END OUTPUT_FO; 
+0

は、私が "SELECT INTO" の使用を混乱しました。複合型を初期化しなければなりませんでした。 –

+0

右、 'TMPLINE'を初期化しなければなりません。 –

0

CREATE OR REPLACE FUNCTION OUTPUT_FO RETURN FO_OUTPUT_TABLE AS 
    RETVAL FO_OUTPUT_TABLE := FO_OUTPUT_TABLE(); 
BEGIN 
    FOR I IN (SELECT SUBSTR(ACC.ACCOUNTNUMBER_, 1, 10) AS NUMCPT, 
        ACC.ACCOUNTNUMBER_ AS ACTIONACCOUNT 
       FROM ACCOUNTCONTRACT ACC 
      WHERE ROWNUM < 10) LOOP 

    RETVAL.EXTEND; 
    RETVAL(RETVAL.COUNT) := FO_OUTPUT(I.NUMCPT, I.ACTIONACCOUNT); 
    END LOOP; 
    RETURN(RETVAL); 
END OUTPUT_FO; 
+1

この場合、 'TMPLINE'は必要ありません。 –

+0

@FrankOckenfuss:あなたは大丈夫です –

1

使用BULK COLLECT INTO

CREATE OR REPLACE FUNCTION OUTPUT_FO 
RETURN FO_OUTPUT_TABLE 
AS 
    RETVAL FO_OUTPUT_TABLE; 
BEGIN 
    SELECT FO_OUTPUT(
      SUBSTR(ACC.ACCOUNTNUMBER_, 1, 10), 
      ACC.ACCOUNTNUMBER_ 
     ) 
    BULK COLLECT INTO RETVAL 
    FROM ACCOUNTCONTRACT ACC 
    WHERE ROWNUM < 10; 

    RETURN RETVAL; 
END OUTPUT_FO; 
/
+0

スピードとパフォーマンスを考慮すると、BULKは私が回答セクションに書いたコードより効率的で高速ですか? –

+1

[Oracle](https://community.oracle.com/thread/2353407?start=0&tstart=0)は、カーソルのFORループを(内部的に)バルク・コレクト(可能な場合)に変換します。したがって、パフォーマンスにはほとんど差がないかもしれませんが、コードがよりシンプル(読み込みと保守)かどうかを比較することもできます。より効果的なものを見つけるための最も簡単な方法は、システム上でそれを実際にプロファイリングすることです。 – MT0