【问题标题】:Sorting an index-by table (associative array)按索引表排序(关联数组)
【发布时间】:2020-02-21 21:03:10
【问题描述】:

我需要对定义为“二进制整数索引表”的关联数组进行排序。我可以手动编写快速排序算法,但肯定有办法对我的值进行排序使用查询(排序依据)

我的问题说明:

我的关联数组类型的定义:

create or replace package my_type is 
   type my_array is table of NUMBER index by binary_integer;
end my_type ;

出于测试目的,让我们生成一个测试数组,其中包含或未按升序排序的值。

declare
  test my_array.my_type.;
  i number := 10;

begin
  while (i > 0) loop
       test(10 - i) :=  i;
       i := i - 1;
  end loop;
end;

我想使用带有 ORDER BY 的查询按升序对该数组进行排序。类似的东西:

  i := 0;
  for query_result_row in (select 1 as val from table(test) order by 1) loop
     test(i) := query_result_row.val;
     i := i + 1;
  end loop;

这种方法应该是可行的:“Oracle 12c 支持使用 TABLE 运算符查询关联数组,只要在包规范中声明了类型:https://galobalda.wordpress.com/2014/08/02/new-in-oracle-12c-querying-an-associative-array-in-plsql-programs/

我怀疑问题出在我选择带有序数的列的方式上。这显然是不可能的,但是没有列名(因为它是一个关联数组),所以我被卡住了。

【问题讨论】:

  • 不,给出的答案不是我要找的答案,我想使用 TABLE 运算符查询关联数组。将所有内容转换为另一个集合并不是我想要的:如果这是绝对必要的,我最好使用手动编码的快速排序算法。

标签: sql oracle plsql


【解决方案1】:

使用 TABLE 运算符查询关联数组有效。正如我一样,问题来自列选择,它不适用于序数。对于通过表运算符的关联数组,要选择的列名是 COLUMN_VALUE。

已完成的解决方案:

我的关联数组类型的定义:

create or replace package my_type is 
   type my_array is table of NUMBER index by binary_integer;
end my_type ;

生成具有或未按升序排序的值的测试数组并对它们进行排序:

declare
  test my_array.my_type.;
  i number := 10;

begin
  -- Generating a test array with values that or not sorted in asc order
  while (i > 0) loop
       test(10 - i) :=  i;
       i := i - 1;
  end loop;

-- Sorting the values :
for query_result_row in (SELECT COLUMN_VALUE from table(test) order by 1) loop
   i := i + 1;
   test(i) = query_result_row.COLUMN_VALUE;
end loop;

【讨论】:

    【解决方案2】:

    您甚至可以使用 BULK COLLECT 为自己节省一些分配代码行:

    DECLARE
      test my_array.my_type;
      i number := 10;
      CURSOR c IS
        SELECT t.column_value
        FROM table(test) t
        ORDER BY t.column_value;
    begin
      -- Generating a test array with values that or not sorted in asc order
      while (i > 0) loop
           test(10 - i) :=  i;
           i := i - 1;
      end loop;
    
      OPEN c;
      FETCH c BULK COLLECT INTO test;
      CLOSE c;
    END;
    

    注意:您不能只使用 BULK COLLECT INTO 编写 SELECT。看来 Oracle 在运行语句之前清空了集合。您不会收到错误消息,但也不会收到任何结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-03
      • 1970-01-01
      • 2014-06-10
      • 1970-01-01
      • 1970-01-01
      • 2019-12-11
      相关资源
      最近更新 更多