WingYip
asked on
Use variable for IN clause
Hi
I want to run a delete stored proc on a table like the following
DELETE FROM bb_classes
WHERE ( AccountNo_FK = @AccountNo
AND ClassName NOT IN ( @ExludeClasses )
Classname is an nvarchar(50) datatype - could be Class 1 or Class 2 etc
Not having much luck getting this to work
How should the @ExcludeClasses parameter be constructed?
Wing
I want to run a delete stored proc on a table like the following
DELETE FROM bb_classes
WHERE ( AccountNo_FK = @AccountNo
AND ClassName NOT IN ( @ExludeClasses )
Classname is an nvarchar(50) datatype - could be Class 1 or Class 2 etc
Not having much luck getting this to work
How should the @ExcludeClasses parameter be constructed?
Wing
IN works against a subquery (which requires a select statement) or a list. In your case, surrounding the variable with a pair of single quotes may work. For example,
DELETE FROM bb_classes
WHERE ( AccountNo_FK = @AccountNo
AND ClassName NOT IN ( '' + @ExludeClasses + '')
Note, there is a typo in the variable name for this post (@ExludeClasses), which, I assume, you do not have in the actual query.
DELETE FROM bb_classes
WHERE ( AccountNo_FK = @AccountNo
AND ClassName NOT IN ( '' + @ExludeClasses + '')
Note, there is a typo in the variable name for this post (@ExludeClasses), which, I assume, you do not have in the actual query.
If you do not want to create a function as ralmada mentioned, try like this.
DELETE FROM bb_classes
WHERE (AccountNo_FK = @AccountNo
AND ClassName NOT IN (SELECT Ltrim(Substring(ExcludeClasses,n,Charindex(',',ExcludeClasses + ',',n) - n)) AS ExcludeClasses
FROM (SELECT @ExcludeClasses ExcludeClasses) AS t1
CROSS JOIN (SELECT NUMBER
FROM MASTER..spt_values
WHERE TYPE = 'P') AS Numbers(n)
WHERE Substring(',' + ExcludeClasses,n,1) = ','
AND n < Len(ExcludeClasses) + 1))
I had written an article about that:
https://www.experts-exchange.com/A_1536.html
https://www.experts-exchange.com/A_1536.html
Splitting up strings using a separator is a fairly nasty solution - though until recently, was the only solution. Instead, you can use the new User Defined Table Type (UDTT) that SQL Server 2008 provides.
Create the UDTT and stored proc:
CREATE TYPE [dbo].[udttClassName] AS TABLE(
[ClassName] nvarchar(50) NOT NULL)
GO
CREATE PROCEDURE dbo.DeleteClasses(
@AccountNo as varchar(20),
@ExcludeClasses as udttClassName READONLY
)
AS
DELETE FROM bb_classes
WHERE AccountNo_FK = @AccountNo
AND ClassName NOT IN (SELECT ClassName FROM @ExcludeClasses)
GO
Execute your stored proc this way:
DECLARE @ClassNames as udttClassName
INSERT INTO @ClassNames SELECT 'Class1' UNION
SELECT 'Class2'
EXEC DeleteClasses '123', @ClassNames
Create the UDTT and stored proc:
CREATE TYPE [dbo].[udttClassName] AS TABLE(
[ClassName] nvarchar(50) NOT NULL)
GO
CREATE PROCEDURE dbo.DeleteClasses(
@AccountNo as varchar(20),
@ExcludeClasses as udttClassName READONLY
)
AS
DELETE FROM bb_classes
WHERE AccountNo_FK = @AccountNo
AND ClassName NOT IN (SELECT ClassName FROM @ExcludeClasses)
GO
Execute your stored proc this way:
DECLARE @ClassNames as udttClassName
INSERT INTO @ClassNames SELECT 'Class1' UNION
SELECT 'Class2'
EXEC DeleteClasses '123', @ClassNames
VBisMe,
the main issue is still the same: the input comes from the end-user, so you have to "split" the data (1 string) into several strings anyhow?
the main issue is still the same: the input comes from the end-user, so you have to "split" the data (1 string) into several strings anyhow?
I don't see anywhere in the above requirement that he specified that he must use a comma separated string as a parameter for his stored procedure.
On the flip side, if you want to pass a sring, then you don't need to split them at all. You can simply perform a LIKE statement as follows. Note: Start/End string commas are required to ensure the full ClassName is matched.
DELETE FROM bb_classes
WHERE AccountNo_FK = @AccountNo
AND (',' + @ExcludeClasses + ',') NOT LIKE ('%,' + ClassName + ',%')
Personally, I'd use a UDTT.
On the flip side, if you want to pass a sring, then you don't need to split them at all. You can simply perform a LIKE statement as follows. Note: Start/End string commas are required to ensure the full ClassName is matched.
DELETE FROM bb_classes
WHERE AccountNo_FK = @AccountNo
AND (',' + @ExcludeClasses + ',') NOT LIKE ('%,' + ClassName + ',%')
Personally, I'd use a UDTT.
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
set @excludeclasses = 'class1,class2,class3'
Then you can
1) create the parmstolist function attached below
2) use it in your delete query like this
DELETE FROM bb_classes
WHERE ( AccountNo_FK = @AccountNo
AND ClassName NOT IN (select [Value] from dbo.parmstolist(@ExludeCla
Open in new window