2017-04-26 5 views
0

order by 절에있는 일부 동적 정보를 기반으로 중첩 테이블을 정렬하는 데 문제가 있습니다. 여기 동적 정보를 기반으로 중첩 테이블 정렬

내가 ( https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/)

발견 한 내용의 샘플입니다 만 여기에 차이가 나는

SELECT CAST(MULTISET(SELECT * 
         FROM TABLE(table_a) 
         ORDER BY P_SORT_COLUMN P_DIRECTION 
        ) as table_typ) 
    INTO table_b 
    FROM dual; 

그래서 해결하기 위해 동적으로 ORDER BY 절에서 열 및 방향을 정의 할 필요가있다 내가 동적 SQL을 사용하여 생각 생각 및 양식이 동적으로

loc_sql_stmt VARCHAR2(500); 



BEGIN 

    loc_sql_stmt := 'SELECT CAST(MULTISET(SELECT * ' || 
              'FROM TABLE(P_TABLE_A) ' || 
              'ORDER BY P_COLUMN P_DIRECTION ||) as table_typ) ' || 
          'INTO P_TABLE_B' || 
          'FROM dual;'; 


    EXECUTE IMMEDIATE loc_sql_stmt 
      USING IN P_TABLE_A, P_COLUMN, P_DIRECTION, P_TABLE_B; 

END; 

을 할 수 없기 때문에 나는 EXECUTE IMME에서 얻을 오류가 발동에 넣어 DIATE 라인이 "ORA-00936 missing expression

주어진 열과 방향에 따라 네스트 테이블을 정렬하는 더 나은 방법이 있거나이 동적 SQL을 작동시키는 방법은 무엇입니까?

가 DB에이를 만듭니다 :

CREATE OR REPLACE TYPE table_obj AS OBJECT(
        column1  VARCHAR2(20), 
        column2  VARCHAR2(20)); 

    CREATE OR REPLACE TYPE table_typ AS TABLE OF table_obj; 

을 다음 샘플 실행 : 당신이 열/방향 선택이 제한되어 있으면

DECLARE 
    table_a   table_typ := table_typ(); 
    table_b   table_typ := table_typ(); 
    loc_idx   NUMBER; 
    loc_sort_column INTEGER := 1; 
    loc_desc   VARCHAR2 (4); 
    P_SORT_COLUMN  VARCHAR2 (100) := 'column1'; 
    P_DIRECTION  VARCHAR2 (4) := 'DESC'; 
    loc_sql_stmt  VARCHAR2 (500); 
BEGIN 
    FOR i IN 1 .. 5 
    LOOP 
     loc_idx := table_a.COUNT + 1; 
     table_a.EXTEND; 
     table_a (loc_idx) := table_obj (NULL, NULL); 

     table_a (loc_idx).column1 := TO_CHAR (loc_idx); 
     table_a (loc_idx).column2 := TO_CHAR (loc_idx); 
    END LOOP; 

    -- 
    loc_sql_stmt := 
    'SELECT CAST(MULTISET(SELECT * ' || 
          'FROM TABLE(' || table_a || ') ' || 
          'ORDER BY ' || P_SORT_COLUMN || ' '|| P_DIRECTION || 
         ') as table_typ) ' || 
     'INTO :table_b' || 
     'FROM dual'; 

    EXECUTE IMMEDIATE loc_sql_stmt USING IN OUT table_a, table_b; 

FOR i IN 1 .. table_b.COUNT 
LOOP 
    DBMS_OUTPUT.PUT_LINE (table_b (i).rx_number); 
END LOOP; 
END; 

답변

1

loc_sql_stmt VARCHAR2(500); 

BEGIN 

    loc_sql_stmt := 'SELECT CAST(MULTISET(SELECT * ' || 
              'FROM TABLE('|| P_TABLE_A || ') ' || 
              'ORDER BY ' || P_COLUMN || ', ' || P_DIRECTION || ') as table_typ) ' || 
          'INTO :P_TABLE_B' || 
          'FROM dual;'; 


    EXECUTE IMMEDIATE loc_sql_stmt 
      USING OUT P_TABLE_B; 
END; 

편집 된 버전과 같이, 동적 명령문 사용 연결을 구축, 매개 변수의 이름 앞에 고유 동적 SQL 사용 :에 변수를 전달하려면 :

지금 코드를보고 난 당신이 무엇을 필요로하는지 알고 있습니다. 나는 케이스를 사용하여 시도했다

DECLARE 
    table_a table_typ := table_typ(); 
    table_b table_typ := table_typ(); 
    loc_idx NUMBER; 
    loc_sort_column INTEGER := 1; 
    loc_desc VARCHAR2(4); 
    P_SORT_COLUMN VARCHAR2(100) := 'column1'; 
    P_DIRECTION VARCHAR2(4) := 'desc'; 
    loc_sql_stmt VARCHAR2(500); 
BEGIN 
    FOR i IN 1 .. 5 
    LOOP 
     loc_idx := table_a.COUNT + 1; 
     table_a.EXTEND; 
     table_a(loc_idx) := table_obj(NULL, NULL); 

     table_a(loc_idx).column1 := TO_CHAR(loc_idx); 
     table_a(loc_idx).column2 := TO_CHAR(loc_idx); 
    END LOOP; 

    -- 
    loc_sql_stmt := 'begin SELECT CAST(MULTISET(SELECT * ' || 
        'FROM TABLE(:table_a) ORDER BY ' || P_SORT_COLUMN || ' ' || 
        P_DIRECTION || ') as table_typ) ' || ' INTO :table_b ' || 
        'FROM dual; end;'; 

    EXECUTE IMMEDIATE loc_sql_stmt 
     USING table_a, IN OUT table_b; 

    FOR i IN 1 .. table_b.COUNT 
    LOOP 
     DBMS_OUTPUT.PUT_LINE(table_b(i).column1); 
    END LOOP; 
END; 
+0

나는 이것을 시도했지만 다음과 같은 것을 얻었을 것이라고 생각한다. ORA-06550 : 줄 72, 열 27 : PLS-00306 : '||'에 대한 호출에서 번호 나 유형이 잘못됨 – programmerNOOB

+0

미안하지만 줄 72 열 27은 나에게 아무 말도하지 않고 실제 매개 변수 값으로 실제 코드를 보지 못합니다. 데이터와 구조를 제공하면 솔루션을 찾기가 훨씬 쉬워집니다. – Seyran

+0

위의 예제를 추가했습니다 – programmerNOOB

0

이 사건을하려고 여기에

은 샘플입니다 간단한 예를 들어 주문한 진술 :

select * from tab 
order by case when :order = 'c1_asc' then c1 else null end asc 
     , case when :order = 'c1_desc' then c1 else null end desc 
     , case when :order = 'c2_asc' then c2 else null end asc 
     , case when :order = 'c2_desc' then c2 else null end desc 
/* ... */ 
; 
+0

샘플 코드를 작업하고, 변수 무엇에주의를 지불하고 무엇을 문자 그대로 연결됩니다 우리가 동적 PL/SQL 블록을 사용할 필요가 작동하게하려면하지 네이티브 SQL 여기에있다/디코딩 및 값이 정적 1, columnA 등 .... 때문에 그것은 어떤 이유로 케이스/디코드 – programmerNOOB

+0

양식에서 반환되는 값을 허용하지 않습니다, 죄송합니다; 나는 TOAD를 통해 항상 그렇게하기 때문에 할 수 있다는 것을 안다 : identifier와 TOAD는 대체를한다. –