как получить этот заказ, работая в оракуле пл / sql - PullRequest
0 голосов
/ 23 июля 2010
ORDER BY CASE
   WHEN v_SORT_TYPE = 'ASC' THEN
        CASE 
           WHEN v_SORT_ORDER = 'lname' THEN CAST(lname AS VARCHAR2(45)) || ',' || ROWNUM
           WHEN v_SORT_ORDER = 'code' THEN CAST(code AS VARCHAR2(52)) || ',' || ROWNUM
        END ASC
   WHEN v_SORT_TYPE = 'DSC' THEN
        CASE 
           WHEN v_SORT_ORDER = 'lname' THEN CAST(lname AS VARCHAR2(45)) || ',' || ROWNUM
           WHEN v_SORT_ORDER = 'code' THEN CAST(code AS VARCHAR2(52)) || ',' || ROWNUM
        END DESC                   
END                   

Я пытаюсь написать условия, когда v_SORT_TYPE передается как ASC или DSC. Я получаю ошибку компиляции в этом.

Полагаю, это было бы обычным делом для моих pl / sql SP.

где я иду не так?

Ответы [ 3 ]

2 голосов
/ 24 июля 2010

Вам необходимо переосмыслить заказ на несколько «столбцов».

ORDER BY
  CASE WHEN v_sort_type = 'ASC' AND v_sort_order = 'lname' THEN lname END ASC,
  CASE WHEN v_sort_type = 'DESC' AND v_sort_order = 'lname' THEN lname END DESC,
  CASE WHEN v_sort_type = 'ASC' AND v_sort_order = 'code' THEN cname END ASC,
  CASE WHEN v_sort_type = 'DESC' AND v_sort_order = 'code' THEN cname END DESC

В каждый момент времени будет действовать только один из них, поэтому вы получите (например)

 ORDER BY null ASC,null DESC,code ASC, null DESC

или

 ORDER BY null ASC,lname DESC,null ASC, null DESC
1 голос
/ 24 июля 2010

Альтернативой выражению cut'n'pasted CASE () является формирование запроса в процессе выполнения с помощью динамического SQL.

Вот самое простое возможное демо.

create or replace function get_emps
    ( p_dno in emp.deptno%type
      , p_sort_col in varchar2 := 'EMPNO'
      , p_asc_desc in varchar2 := 'ASC')
    return sys_refcursor
is
    stmt varchar2(32767);
    return_value sys_refcursor;
begin

    stmt := 'select * from emp where deptno = :1';

    if p_sort_col is not null 
    then 
        stmt := stmt ||' order by '||p_sort_col||' '||p_asc_desc;
    end if;

    open return_value for stmt using p_dno;

    return return_value;

end get_emps;
/

И это все в действии ...

SQL> var rc refcursor
SQL> exec :rc := get_emps(20, 'ENAME')

PL/SQL procedure successfully completed.

SQL> print rc

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7369 CLARKE     CLERK           7902 17-DEC-80        800                    20
      7902 GASPAROTTO ANALYST         7566 03-DEC-81       3000                    20
      7876 KULASH     CLERK           7788 23-MAY-87       1100                    20
      7788 RIGBY      ANALYST         7566 19-APR-87       3000                    20
      7566 ROBERTSON  MANAGER         7839 02-APR-81       2975                    20

SQL> exec :rc := get_emps(20, 'SAL', 'DESC')

PL/SQL procedure successfully completed.

SQL> print rc

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7788 RIGBY      ANALYST         7566 19-APR-87       3000                    20
      7902 GASPAROTTO ANALYST         7566 03-DEC-81       3000                    20
      7566 ROBERTSON  MANAGER         7839 02-APR-81       2975                    20
      7876 KULASH     CLERK           7788 23-MAY-87       1100                    20
      7369 CLARKE     CLERK           7902 17-DEC-80        800                    20

SQL>    
0 голосов
/ 23 июля 2010

ASC и DESC являются ключевыми словами.Операторы CASE будут оценивать значение, а не ключевое слово.Одним из вариантов будет динамический SQL (построение строки, а затем выполнение), другим вариантом будет предложение IF на более высоком уровне.Если бы вы сортировали только по числам, вы могли бы умножить на минус 1, но строки сложнее.Я думаю, вы могли бы сделать что-то сумасшедшее, например, иметь вторую таблицу, в которой хранятся строки и порядок сортировки в виде числа, и умножать это число на -1, но мне трудно поверить, что это будет лучше любым мыслимым способом, чем первые два варианта.

...