Oracle
 sql >> Base de données >  >> RDS >> Oracle

Meilleure requête pour atteindre l'index Oracle avec des liaisons et des valeurs nulles

Vous pouvez comparer la colonne et la valeur pour voir si les deux sont nulles ; ou les deux ne sont pas nuls et égaux :

SELECT * FROM MYTABLE 
WHERE ((A is null and :1 is null) or A = :1) 
  AND ((B is null and :2 is null) or B = :2) 
  AND ((C is null and :3 is null) or C = :3) 
  AND ((D is null and :4 is null) or D = :4) 
  AND ((E is null and :5 is null) or E = :5) 

Ce qui n'est pas très joli mais devrait fonctionner. Comme vous le savez déjà, vous ne pouvez pas comparer les valeurs avec null avec égalité, seul le is opérateur.

En fonction de votre logiciel client, vous pourrez peut-être utiliser des variables de liaison nommées pour éviter d'avoir à répéter les liaisons ; sinon, vous pouvez utiliser une sous-requête ou CTE qui prend les liaisons, puis les utilise dans la requête principale. Quelque chose comme :

WITH CTE AS (
  SELECT :1 AS val_1, :2 AS val_2, :3 AS val_3, :4 AS val_4, :5 AS val_5
  FROM DUAL
)
SELECT MT.*
FROM CTE
JOIN MYTABLE MT
  ON ((MT.A is null and CTE.val_1 is null) or MT.A = CTE.val_1) 
 AND ((MT.B is null and CTE.val_2 is null) or MT.B = CTE.val_2) 
 AND ((MT.C is null and CTE.val_3 is null) or MT.C = CTE.val_3) 
 AND ((MT.D is null and CTE.val_4 is null) or MT.D = CTE.val_4) 
 AND ((MT.E is null and CTE.val_5 is null) or MT.E = CTE.val_5) 

L'approche d'index basée sur les fonctions de Gordon pourrait être plus fiable et plus facile à comprendre, tant que vous ne pouvez vraiment jamais avoir de colonnes avec la valeur magique zéro. (J'avais également raté cette ligne dans votre question et je n'avais pas réalisé que vous l'aviez déjà ignoré !)