Using a comma seprated string as rows
i hv a column in which i store comma seprated name, i have to show them as rows in a report..
plz help
As with most things, it depends greatly on your Oracle version (you should always post this information).
In release 11 here's a neat method.
http://laurentschneider.com/wordpress/2009/07/select-from-column-separated-list.html
In release 10 there's REGEXP
http://nuijten.blogspot.com/2009/07/splitting-comma-delimited-string-regexp.html
And it looks like you've been given a pre-10 answer already.
Similar Messages
-
Convert comma separated string in rows
Dear Gurus,
I want to convert comma separated string in rows so as to insert in collection.
e.g. string 1234,2323,23232,2343,34234
Above string should be converted in rows so as to insert in table or collection
Thanks in advance
SanjeevOr slight variation...
SQL> ed
Wrote file afiedt.buf
1 with t as (select '1234,2323,23232,2343,34234' as txt from dual)
2 --
3 select REGEXP_SUBSTR (txt, '[^,]+', 1, level)
4 from t
5* connect by REGEXP_SUBSTR (txt, '[^,]+', 1, level) is not null
6 /
REGEXP_SUBSTR(TXT,'[^,]+',
1234
2323
23232
2343
34234... so it doesn't have to work out how many levels it needs to do, it just keeps going until it get's a no-value (of course that assumes that there is always a value between each comma) -
Using a comma-delimited string in Dynamic SQL
Hi --
If I receive a comma-delimited string as an in parameter, can I simply use that (in string format) when building my dynamic sql?
Thanks,
ChristineThe problem is, that you can not use bind variables
here, only literals. This causes
eventual performance problems.And to avoid the inevitable database performance problems Dmytro mentions you can use a function to convert the string to a varray and select from that. This also avoids having to use dynamic sql.
First you create a varray and conversion function.
SQL> create or replace type tabstr_t as table of varchar2(255)
2 /
Type created.
SQL> create or replace function tabstr (
2 p_str in varchar2,
3 p_sep in varchar2 default ','
4 )
5 return tabstr_t
6 as
7 l_str long default p_str || p_sep;
8 l_tabstr tabstr_t := tabstr_t();
9 begin
10 while l_str is not null loop
11 l_tabstr.extend(1);
12 l_tabstr(l_tabstr.count) := rtrim(substr(
13 l_str,1,instr(l_str,p_sep)),p_sep);
14 l_str := substr(l_str,instr(l_str,p_sep)+1);
15 end loop;
16 return l_tabstr;
17 end;
18 /
Function created.Then you can use these in either regular sql.
SQL> var s varchar2(100)
SQL> exec :s := 'Smith,Scott,Miller'
PL/SQL procedure successfully completed.
SQL>
SQL> select * from emp where ename in
2 (select upper(column_value) from table(tabstr(:s)));
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17-DEC-80 800 20
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10Or in pl/sql.
SQL> var c refcursor
SQL> begin
2 open :c for
3 select * from emp where ename in
4 (select upper(column_value) from table(tabstr(:s)));
5 end;
6 /
PL/SQL procedure successfully completed.
SQL> print c
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17-DEC-80 800 20
7788 SCOTT ANALYST 7566 09-DEC-82 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10 -
Converting comma separated string into rows
for my procedure varchar2 is i/p paramter. i will get this i/p from java. this string value is like 'VTP,VR','VM'.
i want to split taht string into rows ie o/p will be
VTR
VR
VM.
how to do this.Hi,
As always, the solution depends on your data, your requirements, and you Oracle version.
Here's one way:
-- Simulating Java input with a bind variable:
VARIABLE str VARCHAR2 (100)
EXEC :str := 'VTP,VR,VM';
SELECT LEVEL AS n
, REGEXP_SUBSTR ( :str
, '[^,]+'
, 1
, LEVEL
) AS str_part
FROM dual
CONNECT BY LEVEL <= 1 + REGEXP_COUNT (:str, ',')
I'm just guessing that your original string doesn't include single-quotes after VR or before VM. If it does, you can use TRIM to remove them from the string passed back by REGEXP_SUBSTR. -
Working with comma seprated string in column
hi,
RDBMS:Oracle 10gR2
I have a table with following structure
Table : t1
id int
emails varchar2 (200)
newEmail varchar2 (150)
Sample data is as following
id emails newEmail
1 [email protected],[email protected],[email protected] null
2
[email protected],[email protected],[email protected] null
I can use following query to extract data from comma separation to row.
select id,regexp_substr(emails, '[^,]+', 1, rownum) Emails
from t1
connect by level <= length(regexp_replace(emails, '[^,]+')) + 1
Now I have to perform 2 operations
1- find /count email ids per id, to estimate how many ids has single and how much have multiple in emails.I have tried following but it just remain in execution
with Email as
select id,regexp_substr(emails, '[^,]+', 1, rownum) Emails
from t1
connect by level <= length(regexp_replace(emails, '[^,]+')) + 1
select id,emails from email
group by id,emails
having count (id)>1;
2- I want to write update newEmail field from first value in Emails in table t1 and remove updated value from emails field of table. so If emails has 5 email addresses (1,2,3,4,5) in it , after update it will have 4.I a not sure hoow to do that ?
thanksYou need to fix your data model.
Storing multiple values in a single value column is bad database design and breaches the rules of normalization.
SQL> ed
Wrote file afiedt.buf
1 with t as (select 1 as id, '[email protected],[email protected],[email protected]' as stupid_string from dual union all
2 select 2, '[email protected],[email protected],email6.domain.com,[email protected]' from dual)
3 -- ----------------------------------------------------
4 -- END OF TEST DATA - USE QUERY BELOW AGAINST OWN TABLE
5 -- ----------------------------------------------------
6 select id
7 ,level as email_id
8 ,regexp_substr(stupid_string,'[^,]+',1,level) as email
9 from t
10 connect by id = prior id
11 and level <= regexp_count(stupid_string,',')+1
12 and prior sys_guid() is not null
13* order by 1,2
SQL> /
ID EMAIL_ID EMAIL
1 1 [email protected]
1 2 [email protected]
1 3 [email protected]
2 1 [email protected]
2 2 [email protected]
2 3 email6.domain.com
2 4 [email protected]
7 rows selected. -
Comma separated string in rows
Hi All,
I have one table
select * from abcd;
No err
1 rishi,rahul
2 rishi,ak
I want output like:
No ERR
1 rishi
1 rahul
2 rishi
2 ak
i am using the below query for this:
select no,regexp_substr(err,'[^,]+', 1, level) from abcd
connect by regexp_substr(err, '[^,]+', 1, level) is not null
but this query is giving me output:
1
rishi
1
rahul
2
ak
2
rishi
1
rahul
2
ak
if i am using distinct then only desired output is coming.
select distinct no,regexp_substr(err,'[^,]+', 1, level) from abcd
connect by regexp_substr(err, '[^,]+', 1, level) is not null
but i don't want to use distinct because my table has millions of rows and err contains comma separated varchar(6000);
please help me.Something like this?
SQL> ed
Wrote file afiedt.buf
1 WITH table_x AS(
2 SELECT 1 id, 'rishi,rahul' str FROM dual UNION ALL
3 SELECT 2 id, 'rishi,ak' str FROM dual
4 )
5 SELECT id,
6 REGEXP_SUBSTR (str,
7 '[^,]+',
8 1,
9 LEVEL)
10 --LEVEL,
11 --SYS_GUID ()
12 FROM table_x
13 CONNECT BY LEVEL <= LENGTH (REGEXP_COUNT (str, ',')) +1
14 AND PRIOR id = id
15 AND PRIOR Sys_Guid() IS NOT NULL
16* ORDER BY id, LEVEL
SQL> /
ID REGEXP_SUBS
1 rishi
1 rahul
2 rishi
2 ak
Trick here is: the usage of SYS_GUID() i.e. System Global Unique Identifier.
Alternative to this, can also use DBMS_RANDOM.value() here.
Read more here - https://forums.oracle.com/thread/2526535
HTH
-- Ranit -
I know this has been asked many times, and I got the simple solution for converting a (comma separated) string to rows like this:
with t as (select 'aa;bb;cc;dd;ee;ff' as txt from dual)
select regexp_substr (txt, '[^;]+', 1, level)
from t
connect by level <= length(regexp_replace(txt,'[^;]*'))+1;This works fine for one string. But my situation is that I have a table like this:
col1 col2
A aa;bb;cc
B dd
etc.I want to convert this to:
A aa
A bb
A cc
B dd
etc.I can do this with a pipelined function or I can do this with a group by or unique in my sql, e.g.:
with t as (select 'A' as what, 'aa;bb;cc' as txt from dual
union
select 'B' as what, 'dd' as txt from dual)
select unique what,REGEXP_SUBSTR (txt, '[^;]+', 1, level)
from t
connect by level <= length(regexp_replace(txt,'[^;]*'))+1;
W REGEXP_S
A bb
A aa
B dd
A cc
4 rows selected.In this example, with only two records A and B, this is no problem. But in the actual table I am using in my WITH clause, this select is performing slowly due to the UNIQUE.
with t as
(select col1, col2
from mytable
select unique col1, regexp_substr (col2, '[^,]+', 1, level)
from t
connect by level <= length(regexp_replace(col2,'[^,]*'))+1;Anybody with a suggestion how to improve this statement?Hi,
It's very confusing to use "CONNECT BY LEVEL <= x" when there's more than one row.
Generate the highest level you'll ever need in a sub-query (called a counter table ) that is based on a one-row table.
Then join to the counter table in your main query.
For example:
WITH cntr AS
SELECT LEVEL AS n
FROM dual
CONNECT BY LEVEL <= 1 + ( SELECT MAX ( LENGTH ( REGEXP_REPLACE ( col2
, '[^;]'
FROM t
SELECT t.col1
, REGEXP_SUBSTR ( t.col2
, '[^;]+' -- Use + here, not *
, 1
, cntr.n
) AS col2_substr
FROM t
JOIN cntr ON cntr.n <= LENGTH ( REGEXP_REPLACE (col2 || ';', '[^;]'))
ORDER BY t.col1
, cntr.n
;Edited by: Frank Kulash on Oct 23, 2009 12:01 PM -
Splitting of comma delimited string CONNECT BY Clause
Hi ,
I have got a problem in splitting a comma separated strings into rows .
I am explaining the use case below :
i have a table x_imp
--> create table x_imp (id number, int_status varchar2(100),c_ref varchar2(30), s_ref varchar2(30));
I inserted values into the table :
insert into x_imp (id, int_status,c_ref,s_ref) values (1,'a1,a2,a3,a4','A','AS');
insert into x_imp (id, int_status,c_ref,s_ref) values (1,'b1,b2,b3,b4','B', 'BS');
insert into x_imp (id, int_status,c_ref,s_ref) values (1,'c1,c2,c3,c4', 'C', null);
insert into x_imp (id, int_status, cust_ref, site_ref) values (1,NULL, 'D', NULL);
I need to split the comma separated int_status into individual rows . That means my expected result is :
. What I need or looking for as expected result:
1, A, AS, a1
1, A, AS, a2
1, A, AS, a3
1, A, AS, a4
1, B, BS, b1
1, B, BS, b2
1, B, BS, b3
1, B, BS, b4
1, C, null, c1
1, C, null, c2
1, C, null, c3
1, C, null, c4
I currently have a solution using Regex . But this solution uses UNIQUE keyword .
The solution i have currently :
select UNIQUE c_ref,s_ref, regexp_substr(int_status,'[^,]+', 1, level) error_code
from x_imp
connect by regexp_substr(int_status, '[^,]+', 1, level) is not null;
I need a better solution . Any pointers ?
Thanks,
BibinOne way of doing using MODEL clause:
select c_ref, s_ref, res err_code
FROM x_imp
model
partition by ( id, c_ref, s_ref)
dimension by ( 1 rn)
measures( int_status, cast(null as varchar2(100)) res,
nvl(length(regexp_replace(int_status, '[^,]')),0)+1 nb )
(res[for rn from 1 to nb[1] increment 1]=regexp_substr(int_status[1], '[^,]+', 1, cv(rn)))
order by c_ref, s_ref;
C_REF S_REF ERR_CODE
A AS a3
A AS a4
A AS a1
A AS a2
B BS b2
B BS b1
B BS b3
B BS b4
C c4
C c3
C c1
C c2
D
13 rows selected -
Hi,
I want to load a file which is comma separated and contain address .Problem is that address its self comma seprated so how do I differenciate whether comma used for column seprator or it used in address.
for eg.
One person having address like
"c/o AB corp,156 cross lane,USA"
Thanks.....Hi SR_MCTS,
Based on your description, you want to distinguish a comma is used for column separator or used in address column in a text file, then load the data from the text file to SQL Server table.
As per my understanding, if you can replace the comma column separator to another delimiter like semicolon (;), just do it. Then we can select Semicolon {;} as Column delimiter for the Flat File Connection Manager. Or ensure all columns are enclosed in double
quotes ("). Then we can set the double quotes (") as Text qualifier for the Flat File Connection Manager, and the commas will be loaded as part of the string fields.
If you can't have that done, because computers don't know the context of the data, you would have to come up with some kind of rules that decides when a comma represents a delimiter, and when it is just part of the text. I think a custom script component
would be necessary to pre-process the data, identify where a comma is part of an address, and then treat that as one field.
Thanks,
Katherine Xiong
Katherine Xiong
TechNet Community Support -
MODEL clause to process a comma separated string
Hi,
I'm trying to parse a comma separated string using SQL so that it will return the parsed values as rows;
eg. 'ABC,DEF GHI,JKL' would return 3 rows;
'ABC'
'DEF GHI'
'JKL'
I'm thinking that I could possibily use the MODEL clause combined with REGULAR expressions to solve this as I've already got a bit of SQL which does the opposite ie. turning the rows into 1 comma separated string;
select id, substr( concat_string, 2 ) as string
from (select 1 id, 'ABC' string from dual union all select 1, 'DEF GHI' from dual union all select 1, 'JKL' from dual)
model
return updated rows
partition by ( id )
dimension by ( row_number() over (partition by id order by string) as position )
measures ( cast(string as varchar2(4000) ) as concat_string )
rules
upsert
iterate( 1000 )
until ( presentv(concat_string[iteration_number+2],1,0) = 0 )
( concat_string[0] = concat_string[0] || ',' || concat_string[iteration_number+1] )
order by id;
Can anyone give me some pointers how to parse the comma separated string using regexp and create as many rows as needed using the MODEL clause?Yes, you could do it without using ITERATE, but FOR ... INCREMENT is pretty much same loop. Couple of improvements:
a) there is no need for CHAINE measure
b) there is no need for CASE in RULES clause
c) NVL can be applies on measures level
with t as (select 1 id, 'ABC,DEF GHI,JKL,DEF GHI,JKL,DEF GHI,JKL,DEF,GHI,JKL' string from dual
union all
select 2,'MNO' string from dual
union all
select 3,null string from dual
SELECT id,
string
FROM T
MODEL
RETURN UPDATED ROWS
partition by (id)
DIMENSION BY (0 POSITION)
MEASURES(
string,
NVL(LENGTH(REGEXP_REPLACE(string,'[^,]+','')),0)+1 NB_MOT
RULES
string[FOR POSITION FROM 1 TO NB_MOT[0] INCREMENT 1] = REGEXP_SUBSTR(string[0],'[^,]+',1,CV(POSITION))
SQL> with t as (select 1 id, 'ABC,DEF GHI,JKL,DEF GHI,JKL,DEF GHI,JKL,DEF,GHI,JKL' string from dual
2 union all
3 select 2,'MNO' string from dual
4 union all
5 select 3,null string from dual
6 )
7 SELECT id,
8 string
9 FROM T
10 MODEL
11 RETURN UPDATED ROWS
12 partition by (id)
13 DIMENSION BY (0 POSITION)
14 MEASURES(
15 string,
16 NVL(LENGTH(REGEXP_REPLACE(string,'[^,]+','')),0)+1 NB_MOT
17 )
18 RULES
19 (
20 string[FOR POSITION FROM 1 TO NB_MOT[0] INCREMENT 1] = REGEXP_SUBSTR(string[0],'[^,]+',1,CV(POSITION))
21 )
22 /
ID STRING
1 ABC
1 DEF GHI
1 JKL
1 DEF GHI
1 JKL
1 DEF GHI
1 JKL
1 DEF
1 GHI
1 JKL
2 MNO
ID STRING
3
12 rows selected.
SQL> SY. -
Comma delimeted string in IN clause of PL/SQL block
Hi,
I am using string having comma separted string in IN clause of PL/SQL block.
But it does not give me right result.
If i m using sql query then give me result.
I m using oracl 10g and following code. DEPT table having 'miller' and 'cleark' ename rows.
Can you please suggest the other way to get proper result.
declare
cnt number:=0;
strin varchar2(40);
begin
strin:='miller,cleark';
select count(*)
into cnt
from dept
where ename in (strin);
dbms_output.put_line('cnt:-'||cnt);
end;Thanks.Apart from the solutions you've already been given, let's be clear...
user548963 wrote:
I am using string having comma separted string in IN clause of PL/SQL block.
But it does not give me right result.Yes it does, it's giving exactly the expected result for what you have provided. It may not be what you're desiring, but it's absolutely correct.
The IN Clause is expecting multiple arguments to be in the set of data. You are providing it with a single argument... a single string. Just because your string has got commas in it does not make that string into multiple arguments. -
Comma delimited string relating to subreports
I previously opened a discussion called comma delimited string for a report header. The response I received then worked well for 'Year' but not for two other areas I am trying to use it for.
Original Code
Details:
whileprintingrecords;
stringvar Year:= Year+ {@Year} + ", ";
Report Footer:
whileprintingrecords;
stringvar Year;
Left(Year, len(Year)-2);
I needed to modify the code to eliminate duplication in Year and this worked fine. See the code below. I also needed this code for two other areas, Author and School. Without the extra line of code with the 'instr' function the code would always show and error for ' Left(author, len(author)-2);'. It came up with and error saying that the result was less than 0 or not and integer and went into debug mode. I added the instr function line and it worked for most but not all. This is my problem. Either the ' Left(author, len(author)-2);' line or 'If instr(author, {@Author } ) = 0 then' makes data disappear. It will show a comma delimited string for 'Author' on most rows but not from some. The same would be true for' School'. I am not sure what is going on. The code below is what I am currently using in the subreports.
Details:
whileprintingrecords;
stringvar author;
If instr(author, {@Author}) = 0 then
author:= author + {@Author } + ", ";
Report Footer:
whileprintingrecords;
stringvar author;
If instr(author, {@Author } ) = 0 then
author:= author + {@Author } + ", ";
Else
Left(author, len(author)-2);Hi Abhilash,
The code for the @Author is:
If ({Command.chrStatus} = "External")then
{Command.chrSurname} & ", " & {Command.chrFirstname}
Else
{Command.chrSurname(1)} & ", " & {Command.chrFirstname(1)}
The goal of this code was to pull all the authors into one comma delimited string.
eg Smith, Brian; Jones, Barry; Lee, Henry
The same desire was with the Schools and the code was the same. I just don't know why this is returning the blanks.
You mentioned in the last post that this would be better done in an SQL command. Should I open up another discussion because I think this would be the way to go. I just don't know how I can do the same comma delimited code in SQL.
Thanks -
Split Comma Delimited String Oracle
I want to Split Comma Delimited string in oracle9i into rowwise data.i do not want to use Functions or connect by level...
is there any other way from which we can split strings.???
if we use Connect by level method the problem im facing is we cannot use suqueries in Connect by clause...
Edited by: user11908943 on Sep 16, 2009 8:37 AMmichaels2 wrote:
I prefer using XMLTABLE which has superceded XMLSEQUENCE and I personally find it easier to read...Agree, but that would be hard in 9i since it is not implemented ;)Ah! missed that bit (gawd I wish people would upgrade to supported versions)
In still later versions (11g) I prefer
SQL> with t as
select 'a,b,c,d,e' str from dual
select trim(column_value) str
from t, xmltable(('"' || replace(str, ',', '","') || '"'))
STR
a
b
c
d
e
5 rows selected.
Natty! But completely illogical (I mean creating an XMLTABLE from a non-XML string). I'm guessing that's a development of XQuery? -
How can I use & in a text string so that the system doesn't ask for the user to enter a value. eg the string is Joe Blogs & Co. Currently the system asks for the user to enter text.
Ferris
An other option is to change your 'define'-character within SQL*Plus:
SQL> sho define
define "&" (hex 26)
SQL> select 'AAA & BBB' from dual
2 ;
Enter value for bbb:
SQL> set define #
SQL> sho define
define "#" (hex 23)
SQL> select 'AAA & BBB' from dual
2 ;
'AAA&BBB'
AAA & BBB
1 row selected.
Martin -
Passing comma separated string to stored procedure
Hi,
There is thread with same query I created earlier and that was answered. That solution worked if I pass comma separated string containing IDs. But due to changes in the logic, I have to pass usernames instead of userIDs. I tried to modify the solution provided to use with this.
Following the link to previous post :
Re: Passing comma separated string to stored procedure
------Package-------
TYPE refcurQID IS REF CURSOR;
TYPE refcurPubs IS REF CURSOR;
procedure GetAllPersonalQueue (p_user_name in nvarchar2, TestQID OUT Test.refcurQID
, TestPubs OUT Test.refcurPubs);
------Package-------
------Package Body-------
PROCEDURE GetAllPersonalQueue (p_user_name in nvarchar2, TestQID OUT Test.refcurQID, TestPubs OUT Test.refcurPubs) as
BEGIN
Open TestQID for
select id from cfq where name in (p_user_name);
Open TestPubs for
SELECT qid FROM queues WHERE qid in(
select id from cfq where name in (p_user_name));
END GetAllPersonalQueue;
------Package Body-------
Thanks in advance
AdityaHi,
I modified the query as per the solution provided by isotope, after which the logic changed and I am passing username instead of userID in comma separated string.
Following is the changes SP, which does not throw any error, but no data is returned.
PROCEDURE GetAllPersonalQueue (p_user_name in nvarchar2, TestQID OUT Test.refcurQID, TestPubs OUT Test.refcurPubs
) is
--local variable
strFilter varchar2(100);
BEGIN
Open TestQID for
select id, name from cfq where name in
select regexp_substr(p_user_name||',','[a-z]+[0-9]+',1,level)
from dual
connect by level <= (select max(length(p_user_name)-length(replace(p_user_name,',')))+1
from dual)
Open TestPubs for
SELECT qid FROM queues WHERE qid in(
select id from cfq where name in
select regexp_substr(p_user_name||',','[a-z]+[0-9]+',1,level)
from dual
connect by level <= (select max(length(p_user_name)-length(replace(p_user_name,',')))+1
from dual)
END GetAllPersonalQueue;
Edited by: adityapawar on Feb 27, 2009 8:38 AM
Maybe you are looking for
-
How do I create an "Add Row" button (add instance with click activity)
I've been looking through a couple of examples, but the xml is lost on me. I need to learn how to do this for myself because it'd help me out on so many forms. There're forms I just simply cannot do without this function. Where I get lost is the java
-
Unable to see tables or views in DataSource definition
Hello, I have configured and tested my Gateway. I am able to create a data source to the AdventureWorksDW2012 sample database and store the credentials. However I can't see any tables or views to select. I checked the data types and table rest
-
DW8 "could not launch Macromedia Contribute "
I am just using DW8 and Contribute 3 in tandem on my new Windows Vista machine. In Site Definitions, when I hit the 'Administer Site in Contribute' button, the re is a flurry of activity and then I get the message "Dreamweaver could not launch Macrom
-
Songs sync but won't play.
I have an iPhone 4s. When I sync my music, not all of the songs transfer. Some of the ones that do won't play. They have a red circle with a red square in the middle beside the title. How do I fix this?
-
Hi, bought the Q10 in August. From the beginning the camera hasnt been working, not the camera or video recorder. Always comes the text, the camera cant be started. It only works with bbm video. Any ideas?