简体   繁体   中英

How to compare a comma separated value in a column with a string collection in Oracle

I have a column 'name' in Database which has values as 'john,smith'. I'm passing a string variable 'name_respository' to a stored procedure which has values as 'test,test1,john,test2' or 'temp,smith,temp1,temp2'. The string variable 'name_repository' values are generated on runtime, they might be temp or test.

Now here's what I'm trying to do, I'm trying to select rows where name is in name_repository. The problem is I've 'john,smith' as name while name_repository has only one of them.I need to split name variable john and smith and then compare against the collection and return rows.

+----------+----------+
| ID     | Name     |
+----------+----------+
| 1      | john,smith  |
| 2      | james,stone    |
| 3      | john,smith |

Now the variable I pass may have smith or john or james or stone and other junk values. I should be returned rows 1 and 3 if I have smith or john as my parameter.

Query should be something like

Select * from table where name in name_repository

you could split the names like this:

SELECT REGEXP_SUBSTR ( name, '[^,]+', 1, LEVEL) data 
FROM table 
CONNECT BY LEVEL <= LENGTH(name) - LENGTH(REPLACE(txt, ',')) + 1

Use Instr() to find the comma in your parameter
Use Substr() to pick the text from the left and right side of your parameter. Eg:

Substr('john,smith',1,instr('john,smith',',')-1) to give you 'john'
Substr('john,smith',instr('john,smith',',') to give you 'smith'

And then just put those returns into your WHERE clause

Where 'john' in(name_repository) OR 'smith in(name_repository)

OR...just write your own split function... :-)

Look at the following link: link

It seems a compact solution could be the following:

SQL> SELECT str
  2  ,      REGEXP_SUBSTR(str, '[^,]+', 1, LEVEL) AS single_element
  3  ,      LEVEL                                 AS element_no
  4  FROM  (
  5         SELECT ROWNUM AS id
  6         ,      str
  7         FROM   t
  8        )
  9  CONNECT BY INSTR(str, ',', 1, LEVEL-1) > 0
10         AND id = PRIOR id
11         AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL;

STR                            SINGLE_ELEMENT                 ELEMENT_NO
------------------------------ ------------------------------ ----------
X,Y,Z                          X                                       1
X,Y,Z                          Y                                       2
X,Y,Z                          Z                                       3
XXX,Y,ZZ,AAAAA,B,CCC,D,E,F,GGG XXX                                     1
XXX,Y,ZZ,AAAAA,B,CCC,D,E,F,GGG Y                                       2
XXX,Y,ZZ,AAAAA,B,CCC,D,E,F,GGG ZZ                                      3
XXX,Y,ZZ,AAAAA,B,CCC,D,E,F,GGG AAAAA                                   4
XXX,Y,ZZ,AAAAA,B,CCC,D,E,F,GGG B                                       5
XXX,Y,ZZ,AAAAA,B,CCC,D,E,F,GGG CCC                                     6
XXX,Y,ZZ,AAAAA,B,CCC,D,E,F,GGG D                                       7
XXX,Y,ZZ,AAAAA,B,CCC,D,E,F,GGG E                                       8
XXX,Y,ZZ,AAAAA,B,CCC,D,E,F,GGG F                                       9
XXX,Y,ZZ,AAAAA,B,CCC,D,E,F,GGG GGG                                    10

13 rows selected.
Note that the in-line view is required to alias ROWNUM (as it cannot be used directly in the PRIOR clause on line 10).

A simple one might be:

select * from table
where regexp_replace(name,'^.*,','') in name_repository
or regexp_replace(name,',.*'') in name_repository;

The first regexp zaps the first name from the string, the second one the second name.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM