Как получить этот заказ, работая в оракуле пл /sql

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 ответа

Решение

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

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

Альтернативой оператору 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>    

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

Другие вопросы по тегам