Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2005 Forums
 Transact-SQL (2005)
 String to table function

Author  Topic 

itay
Starting Member

6 Posts

Posted - 2011-03-10 : 04:01:59
Hello,
Does someone have a good, fast function that will take a string with a delimiter and return it as a table?

Thanks

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2011-03-10 : 04:10:58
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=25830&SearchTerms=CSVTable
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=76033


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

itay
Starting Member

6 Posts

Posted - 2011-03-10 : 04:14:22
Thanks
Go to Top of Page

sunitabeck
Master Smack Fu Yak Hacker

5155 Posts

Posted - 2011-03-10 : 13:00:27
At my last job, I had to parse strings that had of the order of 20,000 comma-separated tokens in it. (Don't ask *groan*, not my fault, not my design) I tried several methods I found on the web, none of which were giving satisfactory performance. So I wrote one of my own using recursive CTE, which worked well - I thought it performed at least an order of magnitude better than those I found on the web. I don't know how this compares with the ones in khtan's links (or if it is even replicating the same algorithm); I don't recall trying those.

Unfortunately, the company folded, and didn't get to take my masterpiece before the doors closed. So I tried to reproduce it from what I recall. Obviously, I have not tested this as well as I tested the real one which died a premature death along with the company and my job. If you are really looking for performance, give it a try, but just be aware that:

a) Not as well-tested as the ones in the links that khtan gave you.

b) I went to great lengths to avoid function calls, casting etc. in the original, but not in this. So performance may not be what it could be.
declare @tickers varchar(max)
set @tickers = replicate(cast('abcde,' as varchar(max)),10000);
select * from dbo.fnSNMParseString(',', @tickers)


-- and the function
create function dbo.fnSNMParseString
(
@separator CHAR,
@string varchar(max)
)
returns @Result table (row_id int not null primary key, token varchar(8000))
as
begin
declare @len int; set @len = len(@string);
with CTE as
(
select
0 as rowId,
cast(1 as bigint) as beg,
charindex(@separator,@string,1) as nextPos,
cast(null as varchar(max)) as token
union all
select
c.rowId+1 as rowId,
c.NextPos+1 as beg,
case when c.nextPos <> 0 then charindex( @separator, @string, c.nextPos+1) else c.nextPos-1 end as nextPos,
substring(@string,c.beg,case when c.nextPos = 0 then @len else c.nextPos-c.beg end) as token
from
CTE c
where
c.nextPos > -1 or c.rowId = 0
)
insert into @Result
select rowId,token from CTE where rowId <> 0
option (MAXRECURSION 0);

return;
end
GO
And, like they say in legal documents, I make no warranties or merchantability or fitness for any purpose other than for intellectual curiosity :-)
Go to Top of Page

glendcruz
Yak Posting Veteran

60 Posts

Posted - 2011-03-12 : 22:52:34
quote:
Originally posted by sunitabeck

At my last job, I had to parse strings that had of the order of 20,000 comma-separated tokens in it. (Don't ask *groan*, not my fault, not my design) I tried several methods I found on the web, none of which were giving satisfactory performance. So I wrote one of my own using recursive CTE, which worked well - I thought it performed at least an order of magnitude better than those I found on the web. I don't know how this compares with the ones in khtan's links (or if it is even replicating the same algorithm); I don't recall trying those.

Unfortunately, the company folded, and didn't get to take my masterpiece before the doors closed. So I tried to reproduce it from what I recall. Obviously, I have not tested this as well as I tested the real one which died a premature death along with the company and my job. If you are really looking for performance, give it a try, but just be aware that:

a) Not as well-tested as the ones in the links that khtan gave you.

b) I went to great lengths to avoid function calls, casting etc. in the original, but not in this. So performance may not be what it could be.
declare @tickers varchar(max)
set @tickers = replicate(cast('abcde,' as varchar(max)),10000);
select * from dbo.fnSNMParseString(',', @tickers)


-- and the function
create function dbo.fnSNMParseString
(
@separator CHAR,
@string varchar(max)
)
returns @Result table (row_id int not null primary key, token varchar(8000))
as
begin
declare @len int; set @len = len(@string);
with CTE as
(
select
0 as rowId,
cast(1 as bigint) as beg,
charindex(@separator,@string,1) as nextPos,
cast(null as varchar(max)) as token
union all
select
c.rowId+1 as rowId,
c.NextPos+1 as beg,
case when c.nextPos <> 0 then charindex( @separator, @string, c.nextPos+1) else c.nextPos-1 end as nextPos,
substring(@string,c.beg,case when c.nextPos = 0 then @len else c.nextPos-c.beg end) as token
from
CTE c
where
c.nextPos > -1 or c.rowId = 0
)
insert into @Result
select rowId,token from CTE where rowId <> 0
option (MAXRECURSION 0);

return;
end
GO
And, like they say in legal documents, I make no warranties or merchantability or fitness for any purpose other than for intellectual curiosity :-)



Use the split function written by Pisco. It is good one and there are nany others too.
Go to Top of Page

Sachin.Nand

2937 Posts

Posted - 2011-03-13 : 00:23:53
quote:
Use the split function written by Pisco.


Did you mean Peso ???



PBUH

Go to Top of Page

jeffw8713
Aged Yak Warrior

819 Posts

Posted - 2011-03-13 : 12:26:46
Here is a SQLCLR version that is pretty fast: http://sqlblog.com/blogs/adam_machanic/archive/2009/04/26/faster-more-scalable-sqlclr-string-splitting.aspx

Also, this discussion here: http://www.sqlservercentral.com/Forums/Topic695508-338-12.aspx#bm704614 has comparisons of various different methods.

If you are looking for the fastest, review those articles - you will find one or more versions that will work for your particular scenario.

Jeff
Go to Top of Page

glendcruz
Yak Posting Veteran

60 Posts

Posted - 2011-03-13 : 20:32:03
quote:
Originally posted by Sachin.Nand

quote:
Use the split function written by Pisco.


Did you mean Peso ???



PBUH





A typo Error . I mean Peso
Thanks for your observation.
Glen
Go to Top of Page
   

- Advertisement -