0
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 中是很常见的事情。

我哪里错了?

4

3 回答 3

2

您需要将顺序重新考虑为多个“列”。

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
于 2010-07-24T07:04:14.397 回答
1

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>    
于 2010-07-24T08:07:50.207 回答
0

ASC 和 DESC 是关键字。CASE 语句将评估为一个值,而不是关键字。一种选择是动态 SQL(构建一个字符串然后执行),另一种选择是在更高级别使用 IF 子句。如果你只按数字排序,你可以乘以负 1,但字符串更难。我想你可以做一些疯狂的事情,比如有第二个表将字符串和排序顺序存储为一个数字,然后将该数字乘以 -1,但我很难相信这会比前两个选项更好.

于 2010-07-23T17:39:27.617 回答