В Oracle (pre-11.2): как использовать упорядочение результата при использовании cast (collect (...))? - PullRequest
5 голосов
/ 10 декабря 2010

Как использовать упорядочение результата при использовании cast (collect (...))?

У меня есть функция GetStringForTable, определенная так:

FUNCTION GetStringForTable(vTable in TVarCharTable, vDelimeter in varchar default ',') return VarChar2 is
    aResult varchar2(32767);
    i int;
  begin
    if vTable.count = 0 then 
      return '';
    end if;

    for i in 1 .. vTable.Count loop
      if i > 1 then
        aResult := aResult || vDelimeter;
      end if;
      aResult := aResult || vTable(i);
    end loop;
    return aResult;
  end GetStringForTable;

And Iиспользуйте это так:

select
  name,
  rep.GetStringForTable
      ((
          Select 
            cast(collect(name) as TVarCharTable)  
          from 
            contacts
          where 
            debtoraccount = dt.accountnumber
      )
      ,', ' --Delimiter
      ) "Contacts" 
from debtable dt
where name like '%Svein%';

Проблема в том, что результат не упорядочен.Я получаю «Дейв, Боб, Кэрол, Алиса», когда мне хочется «Алиса, Боб, Кэрол, Дейв».Как мне заказать результат?Если пробовал следующее, но ничего не работает:

select
  name,
  rep.GetStringForTable
      ((
          Select 
            cast(collect(name) as TVarCharTable)  
          from 
            contacts
          where 
            debtoraccount = dt.accountnumber
          order by name  <= ORA-00907: missing right parenthesis
      )
      ,', ' --Skilletegn
      ) "Contacts"
from debtable dt
where name like '%Svein%';

и

select
  name,
  rep.GetStringForTable
      ((
        select * from
        (
          Select 
            cast(collect(name) as TVarCharTable)  
          from 
            contacts
          where 
            debtoraccount = dt.accountnumber  <= ORA-00904: string: invalid identifier
          order by name
        )
      )
      ,', ' --Skilletegn
      ) "Contacts"
from debtable dt
where name like '%Svein%';

В идеале я бы хотел упорядочить без изменения функции GetStringForTable.

Кто-нибудь может помочь?

Ответы [ 2 ]

9 голосов
/ 12 декабря 2010
    cast(collect(name order by name) as TVarCharTable)  

Этот синтаксис впервые упоминается в руководстве 11gR1 . Но, похоже, он отлично работает с 10g, хотя это не документировано .

4 голосов
/ 10 декабря 2010

Один из методов заключается в изменении GetStringForTable так, чтобы вывод был упорядоченным (у вас могло быть две функции: одна упорядоченная, а другая нет)обходной путь, но, к сожалению, после дополнительных испытаний ЗАКАЗ не гарантируется.Это будет зависеть от выбранного пути доступа.Тем не менее, это может работать в вашем случае:

SQL> SELECT dNAME,
  2         GetStringForTable((SELECT CAST(COLLECT(eNAME) AS TVarCharTable)
  3                              FROM (SELECT *
  4                                      FROM scott.emp
  5                                     ORDER BY ename) e
  6                                   /* ^^^^^^^^ */
  7                              WHERE e.deptno = dt.deptno),
  8                             ', ' --Delimiter
  9                             ) "Contacts"
 10    FROM scott.dept dt;

DNAME          Contacts
-------------- ----------------------------------------------------
ACCOUNTING     CLARK, KING, MILLER
RESEARCH       ADAMS, FORD, JONES, SCOTT, SMITH
SALES          ALLEN, BLAKE, JAMES, MARTIN, TURNER, WARD
OPERATIONS     

Вы можете каким-то образом заставить ORDER с помощью хитрости материализовать подзапрос, но это помешает оптимизатору использовать большинство эффективных путей, например:

SQL> WITH employee AS (
  2     SELECT *
  3       FROM scott.emp
  4      WHERE ROWNUM > 0 /* will materialize the subquery */
  5      ORDER BY ename
  6  )
  7  SELECT dNAME,
  8         GetStringForTable((SELECT CAST(COLLECT(eNAME) AS TVarCharTable)
  9                              FROM employee e
 10                              WHERE e.deptno = dt.deptno),
 11                             ', ' --Delimiter
 12                             ) "Contacts"
 13    FROM scott.dept dt;

DNAME          Contacts
-------------- -----------------------------------------------------
ACCOUNTING     CLARK, KING, MILLER
RESEARCH       ADAMS, FORD, JONES, SCOTT, SMITH
SALES          ALLEN, BLAKE, JAMES, MARTIN, TURNER, WARD
OPERATIONS
...