sql >> Databasteknik >  >> RDS >> Oracle

Bästa frågan för att träffa Oracle-index med binds och null-värden

Du kan jämföra kolumnen och värdet för att se om båda är null; eller båda är inte-null och lika:

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) 

Vilket inte är särskilt vackert men borde fungera. Som du redan vet kan du inte jämföra värden mot null med likhet, bara is operatör.

Beroende på din klientprogramvara kanske du kan använda namngivna bindningsvariabler för att undvika att behöva upprepa bindningarna; om inte kan du använda en underfråga eller CTE som tar bindningarna och sedan använda dem i huvudfrågan. Något i stil med:

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 funktionsbaserade indexmetod kan vara mer tillförlitlig och lättare att förstå, så länge du verkligen aldrig kan ha några kolumner med det magiska värdet noll. (Jag hade missat den raden i din fråga också och hade inte insett att du redan hade räknat bort det!)




  1. Varför tillåter MySQL explicit predikatlåsning inte INSERT-satser utanför predikatlåset

  2. Hur man använder STRCMP() för att jämföra 2 strängar i MySQL

  3. Fånga MySQL-varningar i Python

  4. SQL Server 2008 - Avancerad sökning/sortering