Oracle 基于动态信息的嵌套表排序

Oracle 基于动态信息的嵌套表排序,oracle,dynamic-sql,nested-table,Oracle,Dynamic Sql,Nested Table,我无法根据ORDERBY子句中的一些动态信息对嵌套表进行排序 这是我发现的一个样本 这里唯一的区别是我需要在ORDERBY子句中动态定义列和方向 SELECT CAST(MULTISET(SELECT * FROM TABLE(table_a) ORDER BY P_SORT_COLUMN P_DIRECTION ) as table_typ) INTO

我无法根据ORDERBY子句中的一些动态信息对嵌套表进行排序

这是我发现的一个样本

这里唯一的区别是我需要在ORDERBY子句中动态定义列和方向

SELECT CAST(MULTISET(SELECT * 
                       FROM TABLE(table_a) 
                      ORDER BY P_SORT_COLUMN P_DIRECTION 
                     ) as table_typ) 
  INTO table_b
  FROM dual;
因此,为了避免这种情况,我考虑使用动态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;
我从执行立即数行得到的错误是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; 

如果您的列/方向选择有限,请按顺序尝试case语句,简单示例如下:

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
/* ... */
;

要将变量传递给本机动态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 OUT P_TABLE_B;
END;
编辑版本:

现在看到你的代码,我明白你需要什么了。要使其工作,我们需要使用动态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;

我尝试过使用case/decode,出于某种原因,因为该值不是静态的1,columnA等等。。。。它不接受从case/decodeok返回的值,抱歉;我知道这是可以做到的,因为我一直都是通过蟾蜍来做的,只是用:identifier,蟾蜍做替换。我想我也试过了,但得到了以下ORA-06550:72行,27列:PLS-00306:调用“| |”的参数的数目或类型错误抱歉,但72行,27列没有对我说什么,我看不到你真正的代码有真正的param值,如果你提供一些数据和结构,它将更容易找到解决方案