Anda dapat membandingkan kolom dan nilai untuk melihat apakah keduanya nol; atau keduanya tidak nol dan sama:
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)
Yang tidak terlalu cantik tetapi seharusnya berhasil. Seperti yang sudah Anda ketahui, Anda tidak dapat membandingkan nilai dengan nol dengan kesetaraan, hanya is
operator.
Tergantung pada perangkat lunak klien Anda, Anda mungkin dapat menggunakan variabel bind bernama untuk menghindari pengulangan binding; jika tidak, Anda dapat menggunakan subquery atau CTE yang mengambil ikatan dan kemudian menggunakannya dalam kueri utama. Sesuatu seperti:
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)
Pendekatan indeks berbasis fungsi Gordon mungkin lebih andal dan lebih mudah dipahami, selama Anda benar-benar tidak dapat memiliki kolom dengan nilai ajaib nol. (Saya juga melewatkan baris itu dalam pertanyaan Anda dan tidak menyadari bahwa Anda telah mengabaikannya!)