Puede comparar la columna y el valor para ver si ambos son nulos; o ambos no son nulos e iguales:
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)
Lo cual no es terriblemente bonito, pero debería funcionar. Como ya sabe, no puede comparar valores contra nulo con igualdad, solo is
operador.
Según el software de su cliente, es posible que pueda usar variables de vinculación con nombre para evitar tener que repetir las vinculaciones; si no, podría usar una subconsulta o CTE que toma los enlaces y luego los usa en la consulta principal. Algo como:
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)
El enfoque de índice basado en funciones de Gordon podría ser más confiable y más fácil de entender, siempre que realmente nunca pueda tener ninguna columna con el valor mágico cero. (¡También me había perdido esa línea en tu pregunta y no me había dado cuenta de que ya la habías descontado!)