2017-04-26 5 views
0

order by節にある動的情報に基づいてネストしたテーブルをソートする際に問題があります。ここで動的情報に基づいてネストしたテーブルをソート

は、私が発見したもののサンプルは、ここでの唯一の違いは、私はそう周りを取得するために動的に句

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

順に列と方向を定義する必要がある(https://technology.amis.nl/2006/05/31/sorting-plsql-collections-the-quite-simple-way-part-two-have-the-sql-engine-do-the-heavy-lifting/

です私はEXECUTE IMMEから取得エラー動的

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; 

あり、私は、動的SQLを使用して考えると考えると、フォームはこの操作を行うことができないようPROCに入れDIATE行には「ORA-00936」の式がありません

どのような列および方向でもネスト・テーブルをソートするには、より良い方法がありますか、またはこの動的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を使用:に変数を渡すには:

今すぐあなたのコードを見て、私はあなたが必要なものを理解しています。それは、我々は、動的PL/SQLブロックを使用する必要があります動作させるために、ここではないネイティブ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

リテラル連結されているもの、私は/ケースを使用してみましたがされますデコードなどの理由で、値がstatic 1、columnAなどではないため、ケース/デコードから返される値を受け入れません。 – programmerNOOB

+0

大変申し訳ありません。私はそれができることがわかっています。なぜなら私はTOADを通じて常にそれをするからです:識別子とTOADは代入を行います。 –

関連する問題