| Author |
Topic  |
|
LarryC74
Yak Posting Veteran
83 Posts |
Posted - 07/18/2012 : 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
India
47023 Posts |
Posted - 07/18/2012 : 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/
|
 |
|
|
LarryC74
Yak Posting Veteran
83 Posts |
Posted - 07/18/2012 : 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 |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
India
47023 Posts |
Posted - 07/18/2012 : 11:09:56
|
yep..will wait for details..
------------------------------------------------------------------------------------------------------ SQL Server MVP http://visakhm.blogspot.com/
|
 |
|
|
LarryC74
Yak Posting Veteran
83 Posts |
Posted - 07/18/2012 : 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 |
 |
|
|
robvolk
Most Valuable Yak
USA
15557 Posts |
Posted - 07/18/2012 : 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. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
India
47023 Posts |
Posted - 07/18/2012 : 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/
|
 |
|
|
LarryC74
Yak Posting Veteran
83 Posts |
Posted - 07/18/2012 : 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 |
 |
|
|
LarryC74
Yak Posting Veteran
83 Posts |
Posted - 07/18/2012 : 12:18:43
|
Robvolk: even on those other reports it doesn't work...with "All"
Everyday life brings me back to reality |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
India
47023 Posts |
Posted - 07/18/2012 : 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/
|
 |
|
|
LarryC74
Yak Posting Veteran
83 Posts |
Posted - 07/18/2012 : 12:23:06
|
Okay...thanks! I'll get back with you.
Everyday life brings me back to reality |
 |
|
|
LarryC74
Yak Posting Veteran
83 Posts |
|
|
robvolk
Most Valuable Yak
USA
15557 Posts |
Posted - 07/23/2012 : 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. |
 |
|
|
yosiasz
Flowing Fount of Yak Knowledge
USA
1608 Posts |
Posted - 07/23/2012 : 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 |
 |
|
|
Transact Charlie
Flowing Fount of Yak Knowledge
United Kingdom
3425 Posts |
Posted - 07/23/2012 : 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/ |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
India
47023 Posts |
Posted - 07/23/2012 : 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/
|
 |
|
|
LarryC74
Yak Posting Veteran
83 Posts |
Posted - 07/23/2012 : 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 |
 |
|
|
yosiasz
Flowing Fount of Yak Knowledge
USA
1608 Posts |
Posted - 07/23/2012 : 12:48:39
|
have you tried xml as payload ?
<><><><><><><><><><><><><><><><><> If you don't have the passion to help people, you have no passion |
 |
|
|
LarryC74
Yak Posting Veteran
83 Posts |
Posted - 07/23/2012 : 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 |
 |
|
|
yosiasz
Flowing Fount of Yak Knowledge
USA
1608 Posts |
Posted - 07/23/2012 : 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 |
 |
|
|
LarryC74
Yak Posting Veteran
83 Posts |
Posted - 07/24/2012 : 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 |
 |
|
Topic  |
|