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 2008 Forums
 Transact-SQL (2008)
 dbo.SplitFunction() "too many arguments"

Author  Topic 

LarryC74
Yak Posting Veteran

94 Posts

Posted - 2012-07-18 : 10:43:40
Hi,
I've recently started with a new company and there are lots of stored procedures that use "multi-select" values for the reports.

The "multi-select" values are based on services...there can be up to 2200+ different services.

When the parameter values are selected, they are entered in a #temp table which is later called in the procedure like this:
IN (Select element from #temp)

the procedure works fine if you select "some" of the services individually...but if you hit the "Select All" it those an exception error...dbo.cfn_split() has to many arguments.

When I "hard code" the values in the "IN" clause like:
IN (Select Id from tbl_services) it works fine.

any ideas as to why it wouldn't work?

I tested just the function itself in SSRS 2008 by itself and get the same error.
Select * from dbo.cfn_split(@srvc_id,',')


Below is the code for the function:

/****** Object: UserDefinedFunction [dbo].[cfn_split] Script Date: 07/18/2012 09:48:06 ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[cfn_split](@splitstr VARCHAR(max), @splitchar CHAR(1))
RETURNS @split_elements TABLE (eleno int identity(1,1),
element varchar(max))
AS
-- Custom function to split a string based on the delimiter
-- Accepts a string to be splitted & a delimitter
-- Returns a table with all split elements sorted in chronological order
BEGIN
DECLARE @pos INT

SELECT @pos = CHARINDEX ( @splitchar, @splitstr, 0 )
WHILE @pos <> 0
BEGIN
INSERT @split_elements(element) SELECT SUBSTRING(@splitstr, 1, @pos - 1)
SELECT @splitstr = SUBSTRING(@splitstr, @pos + 1, 8000)
SELECT @pos = CHARINDEX ( @splitchar, @splitstr, 0 )
END
INSERT @split_elements(element) VALUES(@splitstr)

RETURN
END



If this can be figured out then this will solve about 20 different tickets that've come in.

any help is a appreciated!
Larry

Everyday life brings me back to reality

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-07-18 : 10:58:51
i dont think so its issue with sql. as you've declare parameter as varchar(max) it should be able to take any number of values separated by delimiter. i think issue is with passing parameter value from SSRS to procedure. did you see how values are getting passed to SSRS. you can run profiler and see how its passing the values back. also does values themselves have charcaters like & inside it?

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

LarryC74
Yak Posting Veteran

94 Posts

Posted - 2012-07-18 : 11:04:25
I'll check the profiler...

The values are integers that are converted to varchar(). Like this: cast(d.srvc_Id as varchar(10)) in (select element from #tsrvc)

Thanks! I'll update you in a bit.

Larry

Everyday life brings me back to reality
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-07-18 : 11:09:56
yep..will wait for details..

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

LarryC74
Yak Posting Veteran

94 Posts

Posted - 2012-07-18 : 11:49:29
For whatever reason it stops at 1786 values. There are a total of 1918 values that need to be entered.

Everyday life brings me back to reality
Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2012-07-18 : 12:06:45
Can you change the logic of the calling procedures so that if they see "ALL" as a parameter they ignore the CSV list and include everything? I'd also recommend using a JOIN rather than an IN() list.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-07-18 : 12:10:11
quote:
Originally posted by LarryC74

For whatever reason it stops at 1786 values. There are a total of 1918 values that need to be entered.

Everyday life brings me back to reality


did you have special characters like & in field whose values are passed to proc?

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

LarryC74
Yak Posting Veteran

94 Posts

Posted - 2012-07-18 : 12:17:49
robvolk: they have filtered that out for some reason. some reports have them others don't.


visakh16: No...no special characters.

I may just end of up re-writing the entire thing. They use the format From tablea, tableb, tablec WHERE tablea.id = tableb.id AND tableb.id=tablec.id I like the 'JOINs' personally.

I've NEVER seen so many temp tables used in stored procedure before in my life....it's craziness.

Everyday life brings me back to reality
Go to Top of Page

LarryC74
Yak Posting Veteran

94 Posts

Posted - 2012-07-18 : 12:18:43
Robvolk: even on those other reports it doesn't work...with "All"

Everyday life brings me back to reality
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-07-18 : 12:20:26
quote:
Originally posted by LarryC74

robvolk: they have filtered that out for some reason. some reports have them others don't.


visakh16: No...no special characters.

I may just end of up re-writing the entire thing. They use the format From tablea, tableb, tablec WHERE tablea.id = tableb.id AND tableb.id=tablec.id I like the 'JOINs' personally.

I've NEVER seen so many temp tables used in stored procedure before in my life....it's craziness.

Everyday life brings me back to reality


so are there same field length they've given for temporary tables as well. or is it getting truncated while you populate temporary table?
put a rint statement inside proc as first statement to check if you're getting entore string value.
or is it getting trucated from ssrs itself?

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

LarryC74
Yak Posting Veteran

94 Posts

Posted - 2012-07-18 : 12:23:06
Okay...thanks! I'll get back with you.

Everyday life brings me back to reality
Go to Top of Page

LarryC74
Yak Posting Veteran

94 Posts

Posted - 2012-07-23 : 10:19:54
We tried this:

In the this article it talks about passing params and tweaking a ssrs global setting

http://social.msdn.microsoft.com/Forums/en-US/sqlreportingservices/thread/cb6ede72-6ed1-4379-9d3c-847c11b75b32

but it didn't work.

Everyday life brings me back to reality
Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2012-07-23 : 10:33:59
Typically if I have to pass a long list of values I'll used fixed-width and binary. This works well for integers as they store in 4 bytes each and I don't have to parse a string. I've never used this for Reporting Services so I don't know if it can be done that way.

Only other option I can think of is to change the report to use 2 variables and split the list evenly, then modify the procedure to accept both. Again I'm not sure if this will work in Reporting Services.
Go to Top of Page

yosiasz
Master Smack Fu Yak Hacker

1635 Posts

Posted - 2012-07-23 : 10:59:05
what kind of reporting tool are they using: custom or SSRS?

<><><><><><><><><><><><><><><><><>
If you don't have the passion to help people, you have no passion
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2012-07-23 : 11:04:22
are you amenable to changing the behavior? If so check out table valued parameters. (that's if reporting services can do that???)

and read this also:
http://www.sommarskog.se/arrays-in-sql.html

Sounds like it's probably *way* more complicated than it needs to be.


Transact Charlie
Msg 3903.. The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
http://nosqlsolution.blogspot.co.uk/
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-07-23 : 11:59:30
quote:
Originally posted by robvolk

Typically if I have to pass a long list of values I'll used fixed-width and binary. This works well for integers as they store in 4 bytes each and I don't have to parse a string. I've never used this for Reporting Services so I don't know if it can be done that way.

Only other option I can think of is to change the report to use 2 variables and split the list evenly, then modify the procedure to accept both. Again I'm not sure if this will work in Reporting Services.



it should work so far as the query behind is written to compare field value against both variables
they might need procedure/sql code to fill the parameter dropdowns with two separate lists of values though

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

LarryC74
Yak Posting Veteran

94 Posts

Posted - 2012-07-23 : 12:20:53
Thanks for all the help!! I'll play around some more with it and get back with you.

Everyday life brings me back to reality
Go to Top of Page

yosiasz
Master Smack Fu Yak Hacker

1635 Posts

Posted - 2012-07-23 : 12:48:39
have you tried xml as payload ?

<><><><><><><><><><><><><><><><><>
If you don't have the passion to help people, you have no passion
Go to Top of Page

LarryC74
Yak Posting Veteran

94 Posts

Posted - 2012-07-23 : 15:21:33
No...but what is odd about it, is that the function will work correctly on some reports but not on others. We've pin pointed 7 out of 28 that it doesn't work in.

I'd have to look up what xml as payload is. I'm a contractor for this particular company trying to correct some reports while a report writer is out on maternity leave, most of these reports were create years ago.

Trial by fire is what they are calling it...for me.

Everyday life brings me back to reality
Go to Top of Page

yosiasz
Master Smack Fu Yak Hacker

1635 Posts

Posted - 2012-07-23 : 16:11:34
Show us the 7 that did not work and 7 that did
by xml payload I meant to say involves sending the parameter as xml instead of comma delimited values
1,5,6,7
<root>
<id>1</id>
<id>5</id>
<id>6</id>
<id>7</id>
</root>

<><><><><><><><><><><><><><><><><>
If you don't have the passion to help people, you have no passion
Go to Top of Page

LarryC74
Yak Posting Veteran

94 Posts

Posted - 2012-07-24 : 09:28:35
Here's part of the procedure...I don't want to put the names of the tables due to HIPPA violations.



Create PROCEDURE [Rep].[ContractedServicesbyProviderandSite]

-- Add the parameters for the stored procedure here

(
@catchment NVARCHAR(MAX),
@ProviderID NVARCHAR(MAX),
@Plan NVARCHAR(MAX),
@str_dt datetime ,
@end_dt datetime ,
@service NVARCHAR(MAX),
@status NVARCHAR(MAX),
@cspecific int
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;



DECLARE
@catchment_rep NVARCHAR(MAX)
set @catchment_rep =@catchment

DECLARE
@ProviderID_rep NVARCHAR(MAX)
set @ProviderID_rep =@ProviderID

DECLARE
@Plan_rep NVARCHAR(MAX)
set @Plan_rep=@Plan

DECLARE
@str_dt_rep datetime
set @str_dt_rep=@str_dt--'1/1/2012'

DECLARE
@end_dt_rep datetime
set @end_dt_rep =@end_dt--'6/30/2012'

DECLARE
@srvc_id NVARCHAR(MAX)
set @srvc_id=@service

DECLARE
@Avail_status NVARCHAR(MAX)
set @avail_status=@status

DECLARE
@clientspecific Int
set @clientspecific=@cspecific

-- Insert statements for procedure here


SELECT
distinct
X.Provider
,X.ProviderID
,X.available_id
,X.available_desc
,X.SiteID
,X.Site
,X.SiteAddress
,x.City
,x.State
,x.Zip
,X.[Plan]
,X.ContractedService
,x.clientspecific
,x.ServiceCode
,x.Srvc_id
,x.EffectiveDate
,x.EndDate
FROM (

Select
From table1 t1, table2 t2 , table3 t3
Where
t1.id = t2.id
and t2.id = t3.id


)X


WHERE
(convert (nvarchar,key_Id) in (SELECT element FROM dbo.cfn_split(@catchment_rep,',')))
AND
(convert (nvarchar,ProviderID) in (SELECT element FROM dbo.cfn_split(@ProviderID_rep,',')))
AND
(convert (nvarchar,ins_id) in (SELECT element FROM dbo.cfn_split(@Plan_rep,',')))
AND
(case when @srvc_id <> -1 and (convert (nvarchar,srvc_id) in (SELECT element FROM dbo.cfn_split(@srvc_id,','))) then 1
when @srvc_id = -1 then 1
end)=1

AND clientspecific = @clientspecific



Highlighted red is the issue...
There are a total of 1918 different services

Everyday life brings me back to reality
Go to Top of Page
    Next Page

- Advertisement -