2016-09-02 3 views
1

많은 경우 this question처럼 함수에서 결과 집합을 반환하고 일반 테이블과 마찬가지로이 결과 집합을 사용하려고하지만 프로 시저 내에서이 작업을 수행하려는 추가 비틀어 짐이 필요합니다. Oracle 버전> = 11 사용).프로 시저의 함수에서 결과 반환

기본적으로 동적 쿼리의 결과를 매우 복잡한 정적 SQL 문의 시작점으로 사용할 수 있습니다.

SQL * PLUS 프롬프트에서 직접 호출하는 경우 여러 가지 솔루션이 있지만 프로 시저에서 실행될 때 모두 실패하는 것 같습니다. 예를 들어, 사용하는 'method4을'

SQL> WITH q AS (SELECT * FROM TABLE(method4.query('select id, pid from 
    2 my_table where rownum < 100'))) 
    3 SELECT * FROM q where rownum <4; 

      ID  PID 
--------------- ---------- 
      72  499 
      11   89 
      13   23 

3 rows selected. 

SQL> CREATE OR REPLACE PROCEDURE test_x (
    2  p_sql IN VARCHAR2, 
    3  p_results OUT SYS_REFCURSOR 
    4 ) IS 
    5  BEGIN 
    6  open p_results for 
    7  WITH q AS (SELECT * FROM TABLE(method4.query(p_sql))) 
    8  SELECT * FROM q where rownum <4; -- this is where the complex logic would go 
    9  END test_x; 
10/

Warning: Procedure created with compilation errors. 

SQL> show errors 
Errors for PROCEDURE TEST_X: 

LINE/COL ERROR 
-------- ----------------------------------------------------------------- 
7/4  PL/SQL: SQL Statement ignored 
7/29  PL/SQL: ORA-22905: cannot access rows from a non-nested table 
     item 

SQL> 

를 내 실제 응용 프로그램에서, 절차의 쿼리는 매우 길고 복잡 할 것입니다. 각 호출에 대해 동적 SQL 생성을 피하고 싶습니다. (그건 내 현재의 '폴백'솔루션입니다.)

스토어드 프로 시저에서 'ANYDATASET 테이블 함수'를 활용할 수있는 방법이 있습니까?

업데이트 : PL/SQL 컨텍스트에서 파이프 라인 된 컨텐츠를 수신 할 수 없다는 통지를 받았습니다. 난 단지가 아닌 파이프 라인 방식으로 나를 잎 있다고 생각 - 초기 SQL의 다음과 같은 비 파이프 라인 아날로그 감안할 때

... 저도 같은 문제를 가지고 있다고 생각합니다 :

SQL> CREATE OR REPLACE FUNCTION myQuery (
    2  p_1 IN VARCHAR2 
    3 ) RETURN ANYDATASET AS p_result ANYDATASET; 
    4  BEGIN 
    5    EXECUTE IMMEDIATE p_1 INTO p_result; 
    6    RETURN(p_result); 
    7 END myQuery; 
    8/

Function created. 

SQL> CREATE OR REPLACE PROCEDURE test_x2 (
    2  p_sql IN VARCHAR2, 
    3  p_results OUT SYS_REFCURSOR 
    4 ) IS 
    5  myset anydataset; 
    6  BEGIN 
    7  myset := method4.query(p_sql); 
    8  open p_results for 
    9  WITH q AS (SELECT * FROM TABLE(myset)) 
10  SELECT * FROM q where rownum <4; -- this is where the complex logic would go 
11  END test_x2; 
12/

Warning: Procedure created with compilation errors. 

SQL> show errors 
Errors for PROCEDURE TEST_X2: 

LINE/COL ERROR 
-------- ----------------------------------------------------------------- 
9/7  PL/SQL: SQL Statement ignored 
9/32  PL/SQL: ORA-22905: cannot access rows from a non-nested table 
     item 

106/13 PLS-00653: aggregate/table functions are not allowed in PL/SQL 
     scope 

그것은 것으로 나타납니다 테이블 함수의 사용은 PL/SQL에서 허용되지 않습니다 - 파이프 라이닝과 무관하게.

결과 스키마가 무엇이든 될 수있는 동적 쿼리를 가져와 PL/SQL 프로 시저 내에서 후속 정적 쿼리에 'with'입력으로 제공하는 다른 방법이 있습니까?

+0

저는 함수의 값을 먼저 변수에 할당해야한다고 생각합니다. 프로 시저 내부에서 함수가 리턴 한 유형의 변수를 선언하고 함수 결과를 해당 변수에 지정하십시오. 그런 다음 변수를'SELECT * FROM TABLE' 문에 사용하십시오. – AndrewMcCoist

+0

@AndrewMcCoist - 제안에 감사드립니다.하지만 변수를 설정 한 행으로 오류를 이동하는 것 같았습니다. ("myset : = method4.query (p_sql);"줄은 ORA-22905 오류를 선택합니다.) – anon

+0

오. 나는 잊었다. 당신의'method4.query'는'PIPELINED' 함수입니까? 그렇다면 PL/SQL 컨텍스트에서 이와 같이 검색 할 수 없습니다. 그것은 당신에게 정규 테이블 타입을 반환해야합니다. – AndrewMcCoist

답변

0

PL/SQL 코드 (CTE 입력 또는 기타 유사한 접근 방식)의 일부로 고정되지 않은 열 집합을 사용하면 코드가 허용되지 않기 때문에이 작업을 수행 할 수 있다고 생각지 않습니다. 미리 컴파일 된. 유일한 대답은 전체 절차를 동적으로 유지하는 것입니다.

나는 내 자신의 질문에 답하는 것이 좋지 않지만이 결론에 이르렀을 때 공개하지 않으려 고하며 다른 사람이 앞으로이 일을 시도 할 때 질문을 삭제하는 것이 좋지 않을 수 있습니다. ..

관련 문제