Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the "IN" clause with a comma delimited string from the output of a replace() function in Oracle SQL

Tags:

oracle

I have an comma delimited string which I want to use in an "IN" clause of the statement. eg: 100,101,102

Since In and "IN" clause I have to quote the individial strings, I use a replace function: eg: select ''''||replace('100,101,102',',',''', ''')||'''' from dual;

The above query works, however, when I try to use the output of the above as an input to the "IN" clause, it returns no data. I am restricted by only SQL statements, so I cannot use PL/SQL code. Kindly help.

select * from employee where employee_number in (
    select ''''||replace('100,101,102',',',''', ''')||'''' from dual);

The above does not work. Please let me know what I am missing.

like image 813
Thomas Avatar asked Jan 12 '11 18:01

Thomas


People also ask

How do I get comma separated values in SQL query?

In order to fetch the comma separated (delimited) values from the Stored Procedure, you need to make use of a variable with data type and size same as the Output parameter and pass it as Output parameter using OUTPUT keyword.

How Split comma separated string and pass to in clause of select statement in Java?

You need to combine two nested statement: Select * From Employee Emp Where Emp. Emp_Name In (Select Regexp_Substr('KING,JONES,FORD' ,'[^,]+' ,1 ,Level) Emp_Name From Dual Connect By Regexp_Substr('KING,JONES,FORD' ,'[^,]+' ,1 ,Level) Is Not Null);


2 Answers

The general approach in this case would be to parse the comma-separated list into an Oracle collection and to use that collection in your SQL statement. Tom Kyte has an example of this in his discussion on variable IN lists.

Assuming you create the myTableType type and the in_list function from that thread, you should be able to do

SELECT *
  FROM employee
 WHERE employee_number IN (
    SELECT *
      FROM TABLE( in_list( p_your_comma_separated_list ) )
    )
like image 68
Justin Cave Avatar answered Oct 31 '22 09:10

Justin Cave


pure SQL, but not very well tested...

select to_number(substr(postfix, 2, instr(postfix, ',' ,2)-2)) id 
  from (
       select substr(val, instr(val, ',', 1, n)) postfix 
         from (select ',101,102,103,' val from dual)
     , (
       select level n
         from dual 
      connect by level < 10) 
  where instr(val, ',', 1, n) > 0)
 where  instr(postfix, ',' ,2)> 2;

EDIT: improved

select substr(postfix, 1, instr(postfix, ',' ,1)-1)
  from (
       select substr(val, instr(val, ',',1, level)+1) postfix
         from (select ',101,102,103,' val from dual)
      connect by instr(val, ',', 2, level) > 0
  );

Note:

  • pre/post fix your strings with comma
  • adopt the upper limit (10 in the example) as per your needs (not needed in the improved version).
  • use the in_list table function mentioned by Justing Cave, that's probably better :)

credit: something like that is in Stephane Faroult's book "Refactorying SQL Applications" (O'Reilly)

like image 27
Markus Winand Avatar answered Oct 31 '22 07:10

Markus Winand