Bạn có thể so sánh cột và giá trị để xem nếu cả hai đều rỗng; hoặc cả hai không-null và bằng nhau:
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)
Nó không đẹp lắm nhưng phải hiệu quả. Như bạn đã biết, bạn không thể so sánh giá trị null với giá trị bằng nhau, chỉ có is
nhà điều hành.
Tùy thuộc vào phần mềm khách hàng của bạn, bạn có thể sử dụng các biến ràng buộc được đặt tên để tránh phải lặp lại các ràng buộc; nếu không, bạn có thể sử dụng một truy vấn phụ hoặc CTE lấy các liên kết và sau đó sử dụng chúng trong truy vấn chính. Một cái gì đó như:
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)
Cách tiếp cận chỉ mục dựa trên chức năng của Gordon có thể đáng tin cậy hơn và dễ hiểu hơn, miễn là bạn thực sự không bao giờ có bất kỳ cột nào có giá trị ma thuật bằng không. (Tôi cũng đã bỏ lỡ dòng đó trong câu hỏi của bạn và không nhận ra rằng bạn đã giảm giá!)