2009-06-02 8 views
1
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 

Вот исключение, которое я получаю, когда я пытался выполнить запрос, показанный вышеКак я могу исправить эту ошибку SQL на этот запрос


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. 

Я был бы очень признателен, если кто-то может указать мне причину этих ошибок

ответ

8

Вы ищете sp_executesql. Сделайте это вместо того, чтобы:

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 

Что вы делаете сейчас пытается вызвать команду как хранимая процедура, которая это явно не так. sp_executesql - это системная хранимая процедура, которая позволяет вам выполнить действительный оператор SQL. Системные хранимые процедуры находятся в основной базе данных FYI.

+0

exec (@q) также будет работать. Вам просто нужно окружить ваш @var в скобках –

+0

, это не сработает: Msg 214, уровень 16, состояние 2, процедура sp_executesql, строка 1 Процедура ожидает параметр '@statement' типа 'ntext/nchar/nvarchar'. –

+0

@KM: Исправлено это nvarchar. Я все время забываю эту зависимость sp_executesql. Однако, как правило, вы должны использовать nvarchar. Не предполагайте, что ASCII сможет охватить все возможные персонажи! – Eric

5

Вы также можете использовать

exec(@q) 

это будет выполнять символьной строки.

Разница в скобках!

+0

Я не поклонник этого метода для удобства чтения. Это делает его жестким, особенно когда у вас есть хранимая процедура, вызывающая кучу SQL и других хранимых процедур. Использование sp_executesql сохраняет эти отдельные достаточно, по крайней мере для меня. Но это только мои предпочтения. – Eric

+0

Эрик, согласен, но для меня это легче запомнить, иногда я забываю sp_executesql. – tekBlues

0

вы пытаетесь выполнить хранимую процедуру @q, которая не является действительным, используйте:

execute (@q) 
0

Ok убедитесь, что вы используете NVARCHAR не VARCHAR. Именно тогда вы можете использовать EXEC sp_executesql @q.

0

объявляют @params NVARCHAR (4000)
объявляют @sql NVARCHAR (4000)

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

SET @sql = «SELECT u.Id FROM [пользователь] 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

0

Или, учитывая то, что вы показываете в качестве кода, я бы вообще не использовал динамический SQL. Dynamic 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 (1, 5, 15) 
Смежные вопросы