May 31, 2006 at 10:35 am
Good Morning All,
I a trying to create a stored procedure that I need to pass a list of values to. But, I cannot figure out how to do this. My query is as such:
CREATE PROCEDURE sp_GetCertainNames
@variable varchar (100) AS
SELECT *
FROM tblTable1
WHERE name IN (@variable)
The data that I'd like to pass would be like:
'Joe','Mary','David'
I'm sure one would need to look at this in another way, thus my contacting you all. Any help would be appreciated...
Thanks!!
May 31, 2006 at 10:55 am
The most common way to do this is to use dynamic SQL and create your SQL String on the fly, e.g.:
CREATE PROCEDURE sp_GetCertainNames
@variable varchar (100) AS
DECLARE @sql varchar(2000)
SET @sql = 'SELECT *
FROM tblTable1
WHERE name IN (' + @variable + ')'
EXEC (@SQL)
The issue is that T-SQL will not accept a variable for an IN list. To use it, you either need to parse the list into a temp table, and use IN (SELECT * From #tmptable), or create a dynamic SQL Statement.
May 31, 2006 at 11:08 am
I like the idea of using a dynamic statement except how do I get the list of names into the procedure incuding the single quotes?
Again,
Thanks for all of your input!!
May 31, 2006 at 11:16 am
"...how do I get the list of names into the procedure incuding the single quotes?"
That depends on the source of the list. I could provide you with Visual Basic 6 code, but if you are coding in ASP.Net, that would not be very useful to you.
May 31, 2006 at 11:21 am
When you specify a string literal (i.e. a readable string value, in quotes), any embedded single quotes are doubled (i.e. into a pair of adjacent single quotes, not into double-quotes). This is so that the SQL parser can read-ahead and see that the first single quote is embedded in, rather than terminating, your literal. SQL server then ignores the second single quote when reading the contents of your string literal. So your call would look like:
declare @nameslist varchar(8000)
select @nameslist = '''Joe'',''Mary'',''David'''
exec sp_GetCertainNames @nameslist
Tim Wilkinson
"If it doesn't work in practice, you're using the wrong theory"
- Immanuel Kant
May 31, 2006 at 2:19 pm
In case of any doubt, I should clarify that you only need to do this for typing strings into the query window (or batch script, etc. - whenever using SQL to specify string values). The data will contain only the single quotes. So if you are getting your data passed to the proc from say an ADO Execute method, the value supplied in your parameter should not have its quotes doubled-up in the way I have described.
Tim Wilkinson
"If it doesn't work in practice, you're using the wrong theory"
- Immanuel Kant
June 1, 2006 at 5:11 am
You shouldn't like the idea, really. Dynamic SQL is a last-resort solution when nothing else have a chance of success. The reason you shouldn't like it, is that it comes with a truckload of consequences, that may not be obvious at first glance, ranging from security implications to maintenance and debugging nightmares.
Dynamic SQL should only be chosen with open eyes.
Please do read this article The curse and blessings of dynamic SQL so that you know what you're getting into.
/Kenneth
June 1, 2006 at 5:32 am
I wouldn't use dynamic SQL for production code, especially non-trivial data retrieval or concatenating parameters from the front end. But I would draw a distinction between production (application) code and administration (utility) code. DDL should never(!) be run from production application code. But to partially automate DDL tasks, especially when the results are checked immediately, use dynamic SQL if you have to.
Of course the need to systematically create new tables might point up problems with your data model. But you might want to implement a template for a certain class of tables (e.g. if they all have certain (extra) columns added to them, need to be added to some maintenance metadata, have special triggers etc.).
Tim Wilkinson
"If it doesn't work in practice, you're using the wrong theory"
- Immanuel Kant
June 1, 2006 at 7:32 am
There are a lot of examples on this website showing you how to do this. The temp table method is best, as no dynamic SQL is required. I have two UDFs. You could do the string parsing part in the fGetTable function if you so desire. Here's the code I use (create the UDFs first):
-- EXAMPLE using your code
SELECT *
FROM tblTable1 t
JOIN dbo.fGetTable(@variable, ',') c
ON t.name = c.code
---------------------------------------------
DROP FUNCTION dbo.fGetTable
DROP FUNCTION dbo.fGetToken
GO
CREATE FUNCTION dbo.fGetToken
(
@parm varchar(8000),
@delim varchar(100),
@whichOccur smallint
)
RETURNS varchar(8000)
AS
BEGIN
DECLARE @occur int, @spos int
DECLARE @token varchar(8000)
SET @occur = 0
WHILE @occur < @whichOccur AND @parm <> '' AND @parm IS NOT NULL
BEGIN
SET @spos = CHARINDEX( @delim , @parm, 1 )
IF @spos = 0
BEGIN
SET @token = @parm
SET @parm = ''
END
ELSE
BEGIN
SET @token = SubString( @parm, 1, @spos - 1)
SET @parm = Substring( @parm, @spos + Len(@delim), Len(@parm) - @spos )
END
SET @occur = @occur + 1
END
IF @occur <> @whichOccur
SET @token = '' -- or NULL
RETURN @token
END
GO
CREATE FUNCTION dbo.fGetTable
(
@codelist varchar(1000),
@delim varchar(10)
)
RETURNS @tbl TABLE (code varchar(1000))
AS
BEGIN
DECLARE @code varchar(1000), @occur int
SET @occur = 1
SET @code = dbo.fGetToken(@codeList, @delim , @occur)
WHILE @code <> ''
BEGIN
INSERT @tbl (code) VALUES (@code)
SET @occur = @occur + 1
SET @code = dbo.fGetToken(@codeList, @delim , @occur)
END
RETURN
END
GO
Viewing 9 posts - 1 through 8 (of 8 total)
You must be logged in to reply to this topic. Login to reply