views:

62

answers:

1

I have the following UDF.

CREATE FUNCTION [dbo].[udf_GenerateVarcharTableFromStringList]
        (@list      varchar(MAX),
         @delimiter char(1) = N',')
    RETURNS @tbl TABLE ([Value]     varchar(200)) 
    WITH SCHEMABINDING
    AS
    BEGIN
       DECLARE @chrind INT
       DECLARE @Piece nvarchar(4000)

       SELECT @chrind = 1
       WHILE @chrind > 0
          BEGIN
            SELECT @chrind = CHARINDEX(@delimiter,@list)
             IF @chrind > 0
                SELECT @Piece = LEFT(@list,@chrind - 1)
             ELSE
                SELECT @Piece = @list
             INSERT @tbl([Value]) VALUES(@Piece)
             SELECT @list = RIGHT(@list,LEN(@list) - @chrind)
             IF LEN(@list) = 0 BREAK
          END

       RETURN

    END

I call this function with the following code example from a where clause in my sprocs:

WHERE u.[Owner] IN 
 (SELECT [VALUE] 
  FROM dbo.udf_GenerateVarcharTableFromStringList(@Owners, ','))

I use this where statement in sprocs that I use for reporting services multivalue parameters. When a user selects jsut blank for the value it returns the correct data but if a user selects a blank value and another value that actualyl has text it does not return the blank value owners anymore, just the owners from the text? Any ideas? I take it something is wrong with the function?

+1  A: 

Well, from what I could gather from your comments it seems that you need a new splitting function. Here's what I use:

create FUNCTION [dbo].[fnSplitString] (@s varchar(512),@sep char(1))
RETURNS table
AS
RETURN (
    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT pn,
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
    FROM Pieces
  )

It has a nice enumeration feature to it and it doesn't eat blanks. :)

Denis Valeev
Perhaps I'm missing something, won't `stop` always be greater than zero?
Thomas
Surely the issue is with what is being sent from Reporting Services anyway. The OP is using multivalue parameters it must default to sending a complete comma delimited list of all values or the `in` would never work.
Martin Smith
It's magic! Haha! :)
Denis Valeev
How do I call this function? The same As I would with mine in a sproc?
@Martin Well, owners are either having a full-fledged value or a downgraded 'empty string', if you pass a CSV ('o1,') you will select all the items that are related to either o1 or '' (not NULL).
Denis Valeev
But, it is generally a bad idea to specify a missing owner by assigning an empty string value to it.
Denis Valeev
I know, I didn't design this I am just writing the queries. SO how do I use this function I say WHERE u.[Owner] IN (SELECT [VALUE] FROM dbo.udf_SplitString(@Owners, ',')) it says invalid column name value.....
This still does not work. It still doesn't pass the blank value into the function
@anicolais I don't know what you are talking about. I mean, there are two kinds of blank, one being an empty string `''` and another is `NULL`. What are you passing to the TVF? If you need `''` on the right side, then embrace the parameter in isnull(@owners,''), if on the other then do isnull(u.owner,''). Hope that helps.
Denis Valeev
I need it to return '' for when I select blank in reporting services. It passes '' to the function when i only select blank but when I select blank and a value it only passes the value....waht do you mean by that last part of your comment? "then embrace the parameter in isnull(@owners,''), " Thanks
@anicolais Then you need to fix the client application. Because it does not behave in a consistent manner. It just has to pass `',15103N'` or `'15103N,'` and not just `'15103N'` because that means gimme all those items that belong to this owner. If you think that by specifying a particular owner should also return all those items without an owner you need to add another predicate which would always returns items that belong to no one. `or isnull(u.owner,'')=''`
Denis Valeev
It is supposed to only show the items belonging to that owner. The problem is if there is not owner and the user selects the blank value option along with another option that is not blank then it only returns the non blank owner because it ignores the blank value.
@anicolais What is the value of @owners in this case? When a user selects two options.
Denis Valeev
If you select blank and 1513ON in the Owners list filter in SSRS it passes @Owners=N'1513ON'
@anicolais It just goes to show that you need to fix your client application and not this stored procedure.
Denis Valeev
Well it ended up actually being an SSRS issue but thanks for all the help. I didn't design the app and this part of it is really bothering me along with others of course but I have no say over it so I just figure out ways around it ;)