Reputation: 12367
I'm trying to formulate the WHERE clause depending on the IN parameters. For this reason I'm doing some experiment on using CASE inside WHERE IN clause. Here's what works fine:
SELECT * FROM TABLE1 WHERE COL1 IN (SELECT ID FROM TABLE2);
Consider that I have an input parameter named P1. The type is not necessary. If the value of P1 is null then the following one also works fine:
SELECT * FROM TABLE1 WHERE COL1 IN (CASE P1 WHEN NULL THEN COL1 ELSE (SELECT ID FROM TABLE2));
But if P1 is not NULL I get
ORA-01427: single-row subquery returns more than one row
error.
If you wonder why I need this, let me explain it quickly. The stored procedure is going to accept many input parameters. Some of them will be a user defined collection type. And all the parameters will be optional with DEFAULT NULL values. So I want to check if a parameter is NULL, if it's the case then compare the column corresponding to the parameter against itself (which means no filter on that column), otherwise filter the column with the value(s) inside the parameter. Is the way I was trying possible somehow?
Upvotes: 2
Views: 1204
Reputation: 726479
Since COL1 IN (COL1)
is the same as true
, you can rewrite your query like this:
SELECT *
FROM TABLE1
WHERE P1 IS NULL OR COL1 IN (SELECT ID FROM TABLE2);
In general, the CASE/WHEN/END
clause can be used only in the "projection" part of a SELECT
; you need to use the "regular" boolean expressions In the WHERE
clause.
Upvotes: 2
Reputation: 27104
Your ELSE
contains a SELECT
that returns more than one row.
Instead you can test for NULL before testing the IN:
SELECT * FROM TABLE1 WHERE (P1 IS NULL) OR (COL1 IN (SELECT ID FROM TABLE2));
Upvotes: 3