SQL Server Forums
Profile | Register | Active Topics | Members | Search | Forum FAQ
 
Register Now and get your question answered!
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 dbo.SplitFunction() "too many arguments"
 New Topic  Reply to Topic
 Printer Friendly
Next Page
Author Previous Topic Topic Next Topic
Page: of 2

LarryC74
Yak Posting Veteran

83 Posts

Posted - 07/18/2012 :  10:43:40  Show Profile  Reply with Quote
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

India
47023 Posts

Posted - 07/18/2012 :  10:58:51  Show Profile  Reply with Quote
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

83 Posts

Posted - 07/18/2012 :  11:04:25  Show Profile  Reply with Quote
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

India
47023 Posts

Posted - 07/18/2012 :  11:09:56  Show Profile  Reply with Quote
yep..will wait for details..

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

Go to Top of Page

LarryC74
Yak Posting Veteran

83 Posts

Posted - 07/18/2012 :  11:49:29  Show Profile  Reply with Quote
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

USA
15557 Posts

Posted - 07/18/2012 :  12:06:45  Show Profile  Visit robvolk's Homepage  Reply with Quote
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

India
47023 Posts

Posted - 07/18/2012 :  12:10:11  Show Profile  Reply with Quote
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

83 Posts

Posted - 07/18/2012 :  12:17:49  Show Profile  Reply with Quote
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

83 Posts

Posted - 07/18/2012 :  12:18:43  Show Profile  Reply with Quote
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

India
47023 Posts

Posted - 07/18/2012 :  12:20:26  Show Profile  Reply with Quote
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

83 Posts

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

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

LarryC74
Yak Posting Veteran

83 Posts

Posted - 07/23/2012 :  10:19:54  Show Profile  Reply with Quote
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

USA
15557 Posts

Posted - 07/23/2012 :  10:33:59  Show Profile  Visit robvolk's Homepage  Reply with Quote
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
Flowing Fount of Yak Knowledge

USA
1608 Posts

Posted - 07/23/2012 :  10:59:05  Show Profile  Click to see yosiasz's MSN Messenger address  Reply with Quote
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
Flowing Fount of Yak Knowledge

United Kingdom
3425 Posts

Posted - 07/23/2012 :  11:04:22  Show Profile  Visit Transact Charlie's Homepage  Reply with Quote
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

India
47023 Posts

Posted - 07/23/2012 :  11:59:30  Show Profile  Reply with Quote
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

83 Posts

Posted - 07/23/2012 :  12:20:53  Show Profile  Reply with Quote
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
Flowing Fount of Yak Knowledge

USA
1608 Posts

Posted - 07/23/2012 :  12:48:39  Show Profile  Click to see yosiasz's MSN Messenger address  Reply with Quote
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

83 Posts

Posted - 07/23/2012 :  15:21:33  Show Profile  Reply with Quote
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
Flowing Fount of Yak Knowledge

USA
1608 Posts

Posted - 07/23/2012 :  16:11:34  Show Profile  Click to see yosiasz's MSN Messenger address  Reply with Quote
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

83 Posts

Posted - 07/24/2012 :  09:28:35  Show Profile  Reply with Quote
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
Page: of 2 Previous Topic Topic Next Topic  
Next Page
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
SQL Server Forums © 2000-2009 SQLTeam Publishing, LLC Go To Top Of Page
This page was generated in 0.17 seconds. Powered By: Snitz Forums 2000