Din fungerande lösning är bra (och liknar vad jag har använt tidigare ). Om du bara vill binda en gång kan du använda en CTE eller inline-vy för att ge värdet till den verkliga frågan:
WITH CTE AS (
SELECT ? AS REAL_VALUE FROM DUAL
)
SELECT C.* -- but not * really, list all the columns
FROM CTE
JOIN CUSTOMERS C
ON (CTE.REAL_VALUE IS NULL AND C.CUSTOMER_ID IS NULL)
OR C.CUSTOMER_ID = CTE.REAL_VALUE
Så det finns bara en platshållare att binda.
Jag ser dock inget problem med en gren på Java-sidan, såvida inte din faktiska fråga är mycket mer komplicerad och skulle leda till betydande dubbelarbete.