Mikayil Abdullayev
Mikayil Abdullayev

Reputation: 12367

Using CASE inside WHERE IN clause

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

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

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

flup
flup

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

Related Questions