2009-08-24 8 views
1

J'ai cette requête qui fonctionne dans Oracle mais je veux la convertir pour utiliser Coalesce en raison de certains problèmes que j'ai avec Visual Studio.Oracle SQL utilisation Coalesce

SELECT * 
FROM a Left Join b on b.institution_code=a.institution_code 
WHERE 
     (upper(a.Login_Name)=UPPER('%' || :Login_Name || '%') OR :Login_Name IS NULL) 
    AND (upper(a.Display_Name) Like UPPER('%' || :Display_Name || '%') OR :Display_Name IS NULL) 
    AND (upper(a.Email_Address)=UPPER(:Email_Address) OR :Email_Address IS NULL) 
    AND ((a.institution_code=:institution_code) OR :institution_code IS NULL) 
    AND (upper(b.institution_desc) Like UPPER('%' || :institution_desc || '%') OR :institution_desc IS NULL) 

Cela fonctionne

WHERE 
Upper(a.Display_Name) LIKE Upper('%' || COALESCE(:Display_Name,a.Display_Name) || '%') 
AND upper(a.Login_Name)=Upper(COALESCE(:Login_Name,a.Login_Name))  
AND upper(a.Email_Address)=Upper(COALESCE(:Email_Address,a.Email_Address)) 

mais lorsque je tente de convertir le champ institution_code et institution_desc à utiliser soudent je ne reçois pas de résultats des requêtes.

quand j'ajouter ces lignes, il n'y a pas de résultats

AND a.institution_code=COALESCE(:institution_code,a.institution_code) 
    AND (Upper(b.institution_desc) LIKE Upper('%' || COALESCE(:institution_desc,b.institution_desc) || '%')) 

Répondre

0

Je soupçonne que le problème est la 2ème ligne (b.institution_desc). Plus précisément, vous avez la possibilité pour une situation NULL LIKE NULL et NULL LIKE NULL renvoie false.

Essayez comme ceci:

AND Upper(b.institution_desc) LIKE '%' || Upper(COALESCE(:institution_desc,b.institution_desc,'')) || '%' 
+0

désolé, mais cela n'a pas fonctionné –

1
WHERE (UPPER(a.Login_Name) = UPPER('%' || :Login_Name || '%') OR :Login_Name IS NULL) 

... devrait être:

WHERE (:Login_Name IS NULL OR UPPER(a.Login_Name) = UPPER('%' || :Login_Name || '%')) 

Vous voulez vérifier la variable de liaison FIRST - sinon vous faites la comparaison des données avant de connaître que vous voulez tout de toute façon. Vous obtenez la pire performance possible de la requête.

Ensuite, si vous allez courir plus haute sur de nombreuses colonnes - utiliser des sous-requêtes Factoring pour avoir réalisé la première:

WITH upper_a AS (
SELECT a.pk, 
     UPPER(a.login_name) 'login_name', 
     UPPER(a.display_name) 'display_name', 
     UPPER(a.email_address) 'email_address', 
     UPPER(b.institution_desc) 'institution_desc' 
    FROM a) 
SELECT * 
    FROM A a 
    JOIN upper_a ua ON ua.pk = a.pk 
WHERE :Login_Name IS NULL OR ua.login_name = v_login_name 

Oracle ne fait pas où (Parmeter IS NULL OU t.col = paramètre), et vous n'obtenez rien en utilisant des variables de liaison pour les paramètres avec des valeurs optionnelles. Ce que vous voulez vraiment utiliser, ce sont les variables CONTEXT (disponibles depuis 9i).

+0

nous avons oracle 8i –

+0

Drats - vous ne pouvez pas utiliser l'affacturage sous-requête ou les variables de contexte jusqu'à 9i. Mais je recommande toujours de ne pas utiliser COALESCE dans le cas de paramètres optionnels pour continuer à faire des scans d'index ou même des scans complets de table inutilement. –

2
AND ((a.institution_code=:institution_code) OR :institution_code IS NULL) 

n'est pas équivalent à

AND a.institution_code=COALESCE(:institution_code,a.institution_code) 

IF a.institution_code IS NULL et: institution_code IS NULL, le premier exemple sera vrai (parce que la deuxième partie de la OR est vrai), mais la seconde ne le sera pas (parce que NULL = NULL n'est pas vrai).