Как получить этот заказ, работая в оракуле пл /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, но мне трудно поверить, что это будет лучше любым мыслимым способом, чем первые два варианта,