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)
 Add ' to a String

Author  Topic 

mickster
Starting Member

10 Posts

Posted - 2011-01-16 : 16:35:30
I pass a string to my stored procedure which is similar to this:

'test1,test2,test3,test4'

SQL Server will not recognise the string like this since each word is not enclosed in quotes. The string needs to appear like this:

'test1','test2','test3','test4'

How do I format the string like this? I will be calling a separate UDF to take care of this but I'm not sure of what I need to do to return the correctly formatted string.

Thanks in advance

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2011-01-16 : 16:59:51
It seems you are dealing with dynamic SQL. Why?
Use a string splitting function and either APPLY or JOIN against the function resultset.



N 56°04'39.26"
E 12°55'05.63"
Go to Top of Page

mickster
Starting Member

10 Posts

Posted - 2011-01-16 : 19:05:19
Here's a bit of background. I have a SSRS report running that has the ability for users to select multiple values. When SSRS passes this parameter to my SQL sp, it passes a single string that is enclosed in quotes (as oposed to enclosing each value in this string in quotes, its a shortcoming of SSRS). Hence the following string:

'Annual Giving 2008, Annual Giving 2009, Annual Giving 2010'

This value is used in the following statement in my sp:


SELECT * FROM #Fundraising
WHERE Fund IN (@Fund)


SQL will not return any results since @Fund does not have quotes around every value. In order for this to work correctly, @Fund needs to have the following value:

'Annual Giving 2008','Annual Giving 2009','Annual Giving 2010'

I hope that makes sense, let me know if I haven't clarified something. I'm looking for a way to get from point a to b, i.e., enclosing each of the values in quotes as ooposed to just having a pair of quotes around the whole string.
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2011-01-16 : 19:08:08
Like Peter said, use a string splitting function instead.

Tara Kizer
Microsoft MVP for Windows Server System - SQL Server
http://weblogs.sqlteam.com/tarad/

Subscribe to my blog
Go to Top of Page

mickster
Starting Member

10 Posts

Posted - 2011-01-16 : 19:32:59
String splitting in SQL is not my forte. I know how to create a function, and I know I need to use CHARINDEX and SUBSTRING. Unfortunately I have no idea how to do it (the actual splitting). I have done my research but I have always found my results lacking.

I can take this string and use a function to split it out to a table, but that doesn't help since the table rows are not what I want; the end result I need should be 1 row.

Below is the function I am using.


ALTER FUNCTION [dbo].[fn_SplitString]
(
@CSVString NVARCHAR(MAX),
@Delimiter NVARCHAR(1)
)
RETURNS @tbl TABLE (Result NVARCHAR(MAX))
AS
BEGIN
DECLARE
@i INT,
@j INT
SELECT @i = 1
WHILE @i <= LEN(@CSVString)
BEGIN
SELECT @j = CHARINDEX(@Delimiter, @CSVString, @i)
IF @j = 0
BEGIN
SELECT @j = LEN(@CSVString) + 1
END
INSERT @tbl SELECT SUBSTRING(@CSVString, @i, @j - @i)
SELECT @i = @j + LEN(@Delimiter)
END

UPDATE @tbl
SET Result = '''' + Result + '''' + ','
RETURN

END


The statement in my SP is below:


SELECT * FROM #Fundraising
WHERE Fund IN (SELECT * FROM fn_SplitString(@Fund,','))


@Fund is set to the following value:

'Annual Giving 2008, Annual Giving 2009, Annual Giving 2010'

At best SQL only displays the results for 'Annual Giving 2008'; the rest are ignored.

I'd appreciate some help since I can't think of a solution myself.

Thanks
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2011-01-16 : 23:26:21
No reason to reinvest the wheel, Peter's done the hard work already: http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=76033

Tara Kizer
Microsoft MVP for Windows Server System - SQL Server
http://weblogs.sqlteam.com/tarad/

Subscribe to my blog
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2011-01-17 : 06:43:30
Also, since you have leading spaces in your string (space after comma), you will get no hit.

SELECT * FROM #Fundraising
WHERE Fund IN (SELECT LTRIM(Result) FROM fn_SplitString(@Fund,','))







N 56°04'39.26"
E 12°55'05.63"
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2011-01-17 : 07:20:03
quote:
Here's a bit of background. I have a SSRS report running that has the ability for users to select multiple values. When SSRS passes this parameter to my SQL sp, it passes a single string that is enclosed in quotes (as oposed to enclosing each value in this string in quotes, its a shortcoming of SSRS)
This is not correct. I captured the resulting SQL from a SSRS report that accepts multiple values using Profiler and the query that is sent to the database looks like this:
SELECT * FROM Calls WHERE a_number IN (N'93018391',N'36372564')
(Numbers are created using a random number generator)
The query in the dataset looks like this:
SELECT * FROM Calls WHERE a_number IN (@Numbers)
The parameter is defined as text and accepts multiple values:



- Lumbago

My blog (yes, I have a blog now! just not that much content yet)
-> www.thefirstsql.com
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2011-01-17 : 07:23:21
And the number parameter is specified in the report like this:



- Lumbago

My blog (yes, I have a blog now! just not that much content yet)
-> www.thefirstsql.com
Go to Top of Page

mickster
Starting Member

10 Posts

Posted - 2011-01-17 : 22:10:30
quote:
Originally posted by Lumbago

quote:
Here's a bit of background. I have a SSRS report running that has the ability for users to select multiple values. When SSRS passes this parameter to my SQL sp, it passes a single string that is enclosed in quotes (as oposed to enclosing each value in this string in quotes, its a shortcoming of SSRS)
This is not correct. I captured the resulting SQL from a SSRS report that accepts multiple values using Profiler and the query that is sent to the database looks like this:
SELECT * FROM Calls WHERE a_number IN (N'93018391',N'36372564')
(Numbers are created using a random number generator)




That's strange, here's the output from the trace I ran on the report with Profiler:


exec sp_executesql N'EXEC sp_AllFundraisingPayments @Fund',N'@Fund nvarchar(37)',@Fund=N'Annual Giving 2008,Annual Giving 2009'


As you can see, it's not passing a properly delimited string to SQL in my case.

Thank you for your function Peter. I copied your ParseList function to see whether I could get my sp to work. However I now get the error below.

quote:
Msg 116, Level 16, State 1, Procedure sp_AllFundraisingPayments, Line 84
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.


Here's the function:

ALTER FUNCTION dbo.fnParseList
(
@Delimiter CHAR,
@Text TEXT
)
RETURNS @Result TABLE (RowID SMALLINT IDENTITY(1, 1) PRIMARY KEY, Data VARCHAR(8000))
AS

BEGIN
DECLARE @NextPos INT,
@LastPos INT

SELECT @NextPos = CHARINDEX(@Delimiter, @Text, 1),
@LastPos = 0

WHILE @NextPos > 0
BEGIN
INSERT @Result
(
Data
)
SELECT SUBSTRING(@Text, @LastPos + 1, @NextPos - @LastPos - 1)

SELECT @LastPos = @NextPos,
@NextPos = CHARINDEX(@Delimiter, @Text, @NextPos + 1)
END

IF @NextPos <= @LastPos
INSERT @Result
(
Data
)
SELECT SUBSTRING(@Text, @LastPos + 1, DATALENGTH(@Text) - @LastPos)

RETURN
END


The statement in my sp which calls this function is below:

SELECT * FROM #Fundraising
WHERE Fund IN (SELECT * FROM fnParseList(',',@Fund))


@Fund contains the following string:
'Annual Giving 2008,Annual Giving 2009'

Thank you in advance.
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2011-01-18 : 02:12:32
My ParseList function returns TWO columns; one RowID and one Data column.
What you want is the Data column. RowID is there to identify the order of Data elements.

SELECT * FROM #Fundraising
WHERE Fund IN (SELECT Data FROM fnParseList(',',@Fund))




N 56°04'39.26"
E 12°55'05.63"
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2011-01-18 : 02:14:49
But beware that since you have IN, the function is called for every record in #FundRaising, so your query is not that efficient.

SELECT      fr.*
FROM #Fundraising AS fr
INNER JOIN (
SELECT DISTINCT
Data
FROM dbo.fnParseList(',', @Fund)
) AS x ON x.Data = fr.Fund



N 56°04'39.26"
E 12°55'05.63"
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2011-01-18 : 03:11:14
quote:
That's strange, here's the output from the trace I ran on the report with Profiler:

exec sp_executesql N'EXEC sp_AllFundraisingPayments @Fund',N'@Fund nvarchar(37)',@Fund=N'Annual Giving 2008,Annual Giving 2009'

The behavior is obviously different when using stored procedures compared to using a standard query, and I guess that makes sense.

- Lumbago

My blog (yes, I have a blog now! just not that much content yet)
-> www.thefirstsql.com
Go to Top of Page

mickster
Starting Member

10 Posts

Posted - 2011-01-18 : 17:01:51
Since the be
Go to Top of Page

mickster
Starting Member

10 Posts

Posted - 2011-01-18 : 17:27:06
Since the behaviour in how SSRS passes multivalue parameters to SQL differs between stored procedures and normal queries, I've opted to drop my stored procedure and just put the query into my SSRS report; it works a charm.

I found the following article:

quote:

Single and Multivalued Parameters
You can define a multivalued parameter by selecting the Multivalued option in the Report Parameters dialog box. If this checkbox is not selected, the parameter is single-valued. Specifying the Multivalued option adds checkboxes to the available values in a parameter drop-down list in the published report. Users can check the values they want (for example, in the Sales Reason Comparisons sample report, users can select multiple products to view the combined sales data for those products). A (Select All) option is added to the available values list automatically for parameters that are defined as multivalued.

When specifying the available values, you can provide a static list of strings or use a query to retrieve available values from a data source. A multivalued parameter must include at least one value. Null values are not allowed.

Writing Queries that Map to Multivalued Report Parameters
You can define a multivalued parameter for any report parameter that you create. However, if you want to pass multiple parameter values back to a query, the following requirements must be satisfied:

The data source must be SQL Server, Oracle, or Analysis Services.

The data source cannot be a stored procedure. Reporting Services does not support passing a multivalued parameter array to a stored procedure.



Thanks for all your help Peter, I certainly learned a lot more about string functions.
Go to Top of Page
   

- Advertisement -