Это не динамический SQL, а основывается на чем-то вроде отложенного разрешения имен.
ВЫПОЛНИТЬ , см. @module_name_var
параметр
DECLARE @sql varchar(300)
SELECT
[name] + '..usp_ComputeDailySales' AS Cmd
INTO #List
FROM
sys.databases d WHERE d.[name] LIKE 'branch%'
OR --Thanks Mitch
d.[name] = 'Headquarters'
WHILE EXISTS (SELECT * FROM #List)
BEGIN
SELECT TOP 1 @SQL = Cmd FROM #List
EXEC @SQL
DELETE #List WHERE Cmd = @SQL
END
Редактировать, после комментария КМ
Да, есть разница, но я уточню:
EXEC (@SQL) означает, что @SQL может быть 'SELECT * FROM foo
' ИЛИ 'DELETE User WHERE 1=1'
;.)
EXEC @SQL означает, что @SQL - это имя объекта. Так что я должен был использовать @ Obj
Итак, вы можете сделать это:
DECLARE @Obj varchar(200)
SELECT @Obj = 'dbo.uspCustomHook'
IF OBJECT_ID(@Obj) IS NOT NULL
EXEC @Obj @p1 = 1, @p2 = 'bob', ...
Это позволяет избежать отложенных ошибок разрешения имен. Когда пакет / процесс скомпилирован, ошибки не возникает, если dbo.uspCustomHook не существует.
Я не использовал эту технику начиная с SQL 2000, и я не знаю, достаточно ли умна SQL 2005 (перекомпиляция на уровне операторов), чтобы выяснить, нужно ли запускать @Obj, потому что он не существует, поэтому его нет попробуй скомпилировать оператор EXEC ...
Это также полезно для кросс-баз данных, запросов одинаковых экземпляров. Вы можете настроить prd-prod, dev-dev и т. Д., Не полагаясь на связанные серверы или жестко закодированные имена баз данных.