2016-06-24 2 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 

내 기능은 다음과 같습니다

내 테이블의 구조는 다음과 같다

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; 

Now 실행할 때 :`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

나는 "속을 선택"의 사용을 혼동. 복합 형을 초기화해야했습니다. –

+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

관련 문제