2014-07-07 5 views
1

J'ai la condition suivante pour écrire une requête dans Oracle.Requête SQL avec décodage et comparaison dans la clause where

J'ai besoin de récupérer tous les enregistrements d'un tableau T1 (il a deux colonnes de date D1 et D2) basé sur deux valeurs dynamiques V1 et V2. Ces V1 et V2 sont transmis dynamiquement à partir de l'application. Les valeurs possibles pour V1 sont 'Inférieur à' ou 'Supérieur à'. La valeur possible pour V2 est un nombre entier.

Recherche i besoin d'écrire:

Si V1 est passé comme 'Moins' et V2 est passé comme 5, alors je dois retourner toutes les lignes T1 OÙ D1-D2 < 5.

Si V1 est passé comme 'Supérieur à' et V2 passé à 8, alors je dois retourner toutes les lignes dans T1 WHERE D1-D2> 8;

Je pourrais penser que cela peut être fait en utilisant une clause CAS dans la clause where. Mais je ne sais pas comment commencer.

Toute aide est grandement appréciée. Merci

+0

Magasin V2 dans une variable et référence dans la clause where. Afin de déterminer la requête basée sur l'opérateur basé dans vous pourriez construire la clause Where dynamiquement http://www.codeproject.com/Articles/20815/Building-Dynamic-SQL-In-a-Stored-Procedure, ou utiliser un Si la clause Else et faire de même sélectionne essentiellement mais avec des opérateurs de comparaison différents – CSharper

+0

Comment est-ce possible? Voulez-vous dire que vous avez une variable, qui pourrait avoir la valeur «Moins que» ou «Plus grand que»? – zaratustra

+0

oui vous avez raison – user1019072

Répondre

3

Vous pouvez écrire cela comme:

select * 
from t1 
where (v1 = 'Less Than' and D1 - D2 < v2) or 
     (v1 = 'Greater Than' and D1 - D2 > v2) 

Une déclaration case n'est pas nécessaire.

+0

J'ai eu la même solution)) vous êtes le premier, je ne vais pas poster le mien. – zaratustra

+0

Cette solution devrait fonctionner. Je vais essayer. – user1019072

1

Essayez ceci:

select * 
from T1 
where case when V1 = 'LESS THAN' THEN D1 - D2 < V2 ELSE D1 - D2 > V2 

Cette suppose que si V1 est égale ou supérieure à la seule autre valeur est supérieure à. Si nécessaire, vous pouvez utiliser plus d'une déclaration de cas, mais cela devrait vous aider à démarrer.

+0

Cette requête n'est pas valide dans Oracle. Vous ne pouvez pas avoir d'opérateurs de comparaison (tels que '=', '<', or '>') dans une instruction 'case'. En outre, l'instruction 'case' n'est pas terminée. – Allan

0

PL/SQL Solution, pas droit avant, mais peut être sur mesure pour complexes logiques!

Créer des objets sql table imbriquée

CREATE TYPE MY_RECORD_TYPE IS OBJECT 
    ( 
     D1 VARCHAR2(100), 
     D2 VARCHAR2(100), 
     D3 VARCHAR2(100), 
     D4 VARCHAR2(100) 
    ); 
    /

    CREATE TYPE MY_TABLE_TYPE IS TABLE OF MY_RECORD_TYPE; 
    /

Voici la fonction qui retourne une table imbriquée.

create or replace function check_me(v1 varchar2,v2 number) 
    return MY_TABLE_TYPE 
    is 
    v_query varchar2(4000); 
    my_cur sys_refcursor; 

    v_record MYTABLE%ROWTYPE; -- Create a local record of table's row type 

    v_nested MY_TABLE_TYPE := MY_TABLE_TYPE(); 

    I NUMBER; 
    begin 
    v_query := 'SELECT * FROM MYTABLE WHERE D1 - D2 '; 
    IF(UPPER(v1) = UPPER('Less Than')) THEN 
     v_query := v_query||' > :V2'; 
    ELSE 
     v_query := v_query||' < :V2'; 
    END IF; 

    DBMS_OUTPUT.PUT_LINE(v_query); 
    OPEN my_cur FOR v_query USING V2; 

    I:=0; 
    LOOP 
     FETCH my_cur INTO v_record; 
     EXIT WHEN my_cur%NOTFOUND; 

     v_nested.EXTEND(1); 
     I := I + 1; 

     /* Copy it into the nested table - Painful!!*/ 
     v_nested(I) := MY_RECORD_TYPE(
             v_record.D1, 
             v_record.d2, 
             v_record.D3, 
             v_record.D4 
            ); 
     END LOOP; 

    CLOSE my_cur;--CLose the cursor 
    return v_nested;--return the nested table 
    end; 
    /

Et vous pouvez exécuter comme,

select * FROM TABLE(check_me(',',5)); 
+0

Ceci est énorme pour la question à portée de main.Pourquoi feriez-vous cela au lieu d'utiliser 'ou'? – Allan

+0

Trop compliqué peut-être @Allan mais pas un mauvais rendement n'est-ce pas? Juste dans le cas de logiques plus complexes. Que faire si l'opération négative elle-même est générique, disons une addition ou autre chose .. Les conditions OR continuent de croître. mais ce pl sql, fonctionne de la même manière. Peut aider quelqu'un, c'est pourquoi je l'ai mentionné en réponse comme premier point. –

+0

En fait, la performance sera pire qu'elle ne devrait l'être. Comme vous concaténéz dans les variables, l'optimiseur aura besoin d'un plan distinct pour chaque variable. Vous vaincre la cache sans raison valable. Vous supprimez également l'avantage d'utiliser un langage natif SQL: au lieu de valider la syntaxe SQL au moment de la compilation, vous le faites au moment de l'exécution. Au fur et à mesure que votre fonction devient plus complexe, les chances d'un cas limite où le SQL est brisé augmente. – Allan