Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Beste Abfrage, um den Oracle-Index mit Bindungen und Nullwerten zu treffen

Sie können die Spalte und den Wert vergleichen, um zu sehen, ob beide null sind; oder beide sind nicht null und gleich:

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) 

Was nicht besonders hübsch ist, aber funktionieren sollte. Wie Sie bereits wissen, können Sie bei Gleichheit keine Werte mit null vergleichen, nur der is Betreiber.

Abhängig von Ihrer Client-Software können Sie möglicherweise benannte Bindungsvariablen verwenden, um zu vermeiden, dass die Bindungen wiederholt werden müssen. Wenn nicht, könnten Sie eine Unterabfrage oder einen CTE verwenden, der die Bindungen übernimmt und sie dann in der Hauptabfrage verwendet. Etwas wie:

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) 

Gordons funktionsbasierter Indexansatz könnte zuverlässiger und einfacher zu verstehen sein, solange Sie wirklich niemals Spalten mit dem magischen Wert Null haben können. (Ich hatte diese Zeile in Ihrer Frage auch übersehen und hatte nicht bemerkt, dass Sie das bereits außer Acht gelassen hatten!)