tags:

views:

740

answers:

4

I found this function which returns three rows for the following query:

select * from dbo.split('1 2 3',' ') 

However, I need to use values from a field instead of '1 2 3'.

I tried:

select * from dbo.split(select top 1 myfield from mytable,' ')

But it fails saying incorrect syntax.

Ideas on how to do this? It doesn't have to use the function above, so feel free to recommend another function or different way to go about it. To clarify, I only need to parse the values from a single row of a single field.

+2  A: 

Have you tried

SELECT dbo.split(myfield, ' ') AS x FROM mytable
Peter Lang
You can't use table value functions like this. The OP clearly states that the function 'returns three rows', so is not a scalar.
Remus Rusanu
Hi Peter, thanks for the answer. However, it looks like Remus is right. I get this error: Cannot find either column "dbo" or the user-defined function or aggregate "dbo.split", or the name is ambiguous.
BrianM
A: 

put the UDF around your column, example

SELECT dbo.split(myfield, ' ')  as SplitValue
FROM mytable
SQLMenace
A: 

You need to apply the split(myfield) function to each row in mytable. When the split function is a table valued function the correct answer is the APPLY operator:

The APPLY operator allows you to invoke a table-valued function for each row returned by an outer table expression of a query.

So the answer must be:

select *
from mytable 
cross apply dbo.split(myfield, ' ');

Example:

create table mytable (myfield varchar(10));
insert into mytable (myfield) values ('1 2 3');
go

create function split (@list varchar(max), @delimiter char(1))
returns @shards table (value varchar(8000))
with schemabinding
as
begin
  declare @i int;
  set @i = 0;
  while @i <= len(@list)
  begin
    declare @n int;
    set @n = charindex(@delimiter, @list, @i);
    if 0 = @n
    begin
       set @n = len(@list);
    end
    insert into @shards (value) 
      values (substring(@list, @i, @n-@i+1));
    set @i = @n+1;
  end
  return;
end
go

select * 
from mytable  
cross apply dbo.split(myfield, ' ');
Remus Rusanu
Tried your solution and it didn't work. Error returned is this: "srgspossiblevalues" (that's the name of my field) is not a recognized table hints option. I'll clarify the question to indicate that I only need to parse the values from one cell.
BrianM
You are translating my example incorrectly into your code. There aren't any table hints. I've expanded my example to a full blown running code sample.
Remus Rusanu
Remus -- Thanks for the reply. I tried using your function and get the same error. Actually, for kicks, I deleted the Split function and ran your entire code block to see if it would work. It returned the same error about table hints: "myfield" is not a recognized table hints option. Given my little experience with advanced sql it's very possible I'm still doing something wrong or misunderstanding your solution. Thanks for your patience and help.
BrianM
Is it SQL 2000 by any chance? APPLY is a new operator valid only for SQL 2005 and up.
Remus Rusanu
Nope, using SQL 2005
BrianM
A: 
EXEC SP_DBCMPTLEVEL 'YOUR_DB_NAME',90;

Should fix the problem of Remus's incompatible code. I just looked into my own db and it was set to level '80' which means it supports <= SQL 2000. After applying the procedure above, the code runs and works perfectly.

Now I just need to find out wtf relies on SQL2000 and breaks in SQL2005...AHH!

This MSDN link will help you determine whether your fn/usp/app layers will be negatively impacted: http://msdn.microsoft.com/en-us/library/bb510680.aspx

Buffalo