views:

366

answers:

7
DECLARE @providerIdList varchar(400)
DECLARE @q varchar(400)

SELECT @q  =  ''

SELECT @providerIdList = '(1, 5, 15)'


SET @q = 'SELECT u.Id FROM [user] u
    LEFT JOIN Provider p ON u.Provider_FK = p.Id
    LEFT JOIN  Providers2Users pu ON pu.user_FK = u.Id 
    LEFT JOIN Provider ap ON ap.Id = pu.provider_fk
    WHERE p.Id  IN ' + @providerIdList




exec @q

Here is the exception that I am getting when I tried to execute query shown above


Msg 203, Level 16, State 2, Line 18
The name 'SELECT u.Id FROM [user] u
    LEFT JOIN Provider p ON u.Provider_FK = p.Id
    LEFT JOIN  Providers2Users pu ON pu.user_FK = u.Id 
    LEFT JOIN Provider ap ON ap.Id = pu.provider_fk
    WHERE p.Id  IN (1, 5, 15)' is not a valid identifier.


I would really appreciate if somebody can point me the cause of these errors

+7  A: 

You're looking for sp_executesql. Do this instead:

DECLARE @providerIdList nvarchar(400)
DECLARE @q nvarchar(400)

SELECT @q  =  N''

SELECT @providerIdList = N'(1, 5, 15)'


SET @q = N'SELECT u.Id FROM [user] u
    LEFT JOIN Provider p ON u.Provider_FK = p.Id
    LEFT JOIN  Providers2Users pu ON pu.user_FK = u.Id 
    LEFT JOIN Provider ap ON ap.Id = pu.provider_fk
    WHERE p.Id  IN ' + @providerIdList

exec sp_executesql @q

What you're doing now is trying to invoke the command as a stored procedure, which it's clearly not. sp_executesql is a system stored procedure, which allows you to execute a valid SQL statement. The system stored procedures are on the master database, FYI.

Eric
exec (@q) will also work. You just need to surround your @var in parenthesis
Eoin Campbell
this will not work: Msg 214, Level 16, State 2, Procedure sp_executesql, Line 1Procedure expects parameter '@statement' of type 'ntext/nchar/nvarchar'.
KM
@KM: Fixed it to be nvarchar. I forget this dependency of sp_executesql all the time. As a rule, you should be using nvarchar, anyway, though. Don't assume ASCII will be able to cover all possible characters!
Eric
+4  A: 

You also can use

exec(@q)

this will execute the literal string.

The difference is in the parenthesis!

tekBlues
I'm not a fan of this method for readability reasons. It makes it tough, especially when you have a stored proc calling a bunch of SQL and other stored procs. Using sp_executesql keeps these separate enough, at least for me. But, that's just my preference.
Eric
Eric, I agree, but for me it's easier to remember, sometimes I forget sp_executesql.
tekBlues
A: 

your trying to execute a stored procedure @q, which is not valid, use:

execute (@q)
KM
A: 

Ok make sure you use NVARCHAR not VARCHAR. Just then you might use EXEC sp_executesql @q.

Maxime
+2  A: 

Sorry...I can't comment yet because of my rep...but using what Eric said, you would have to change your variables to Nvarchar.

Aaron
+1, for a good catch and so you can comment.
Eric
A: 

declare @params NVARCHAR(4000)
declare @sql NVARCHAR(4000)

SET @providerIdList = '(1, 5, 15)'

SET @sql = 'SELECT u.Id FROM [user] u LEFT JOIN Provider p ON u.Provider_FK = p.Id LEFT JOIN Providers2Users pu ON pu.user_FK = u.Id LEFT JOIN Provider ap ON ap.Id = pu.provider_fk WHERE p.Id IN ' + @providerIdList'

SELECT @params = N'@providerIdList VARCHAR OUTPUT'

exec sp_executesql @sql, @params,@providerIdList=@providerIdList

SomeMiscGuy
A: 

Or given what you show as your code, I wouldn't use dynamic SQL at all. Dynamic SQl should be avoided if possible.

SELECT u.Id FROM [user] u    
LEFT JOIN Provider p ON u.Provider_FK = p.Id    
LEFT JOIN  Providers2Users pu ON pu.user_FK = u.Id     
LEFT JOIN Provider ap ON ap.Id = pu.provider_fk    
WHERE p.Id  IN (1, 5, 15)
HLGEM