2010-07-23 4 views
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     

J'essaie d'écrire des conditions pour quand v_SORT_TYPE est passé en ASC ou DSC. Je reçois une erreur de compilation à ce sujet. Je suppose que ce serait une chose commune à faire dans mes SP pls/sql.comment obtenir cette commande en travaillant dans oracle pl/sql

Où est-ce que je vais mal?

+0

Quel est le code d'erreur ORA? Et pourquoi concaténez ROWNUM jusqu'à la fin? –

+0

ROWNUM est concaténé pour toujours obtenir les mêmes lignes d'oracle parce que nous faisons la pagination. Le code d'erreur est 'ORA-00905'. –

+0

si l'action est la même pour ASC et DSC pourquoi la vérifier? –

Répondre

2

Vous devez repenser l'ordre en plusieurs "colonnes".

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 

ou

ORDER BY null ASC,lname DESC,null ASC, null DESC 
+0

Nice - c'est certainement un à classer pour une utilisation future. – joelt

0

ASC et DESC sont des mots-clés. Les instructions CASE vont évaluer à une valeur, pas un mot-clé. Une option serait SQL dynamique (construire une chaîne puis exécuter), une autre option serait d'avoir une clause IF à un niveau supérieur. Si vous ne faisiez que trier par nombre, vous pourriez multiplier par 1 négatif, mais les chaînes sont plus dures. Je suppose que vous pourriez faire quelque chose de fou comme avoir une deuxième table qui stocke les chaînes et trier l'ordre comme un nombre, et multipliant ce nombre par -1, mais j'ai du mal à croire que ce serait mieux de toutes les manières possibles .

1

Un seul d'entre eux seraient en vigueur à un moment donné, alors vous feriez effectivement obtenir (par exemple) L'alternative à une coupe L'instruction 'n'pasted CASE() est de façonner la requête en vol avec SQL dynamique.

Voici la démo la plus simple possible.

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; 
/

C'est en action ...

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>  
Questions connexes