2014-01-16 4 views
4

Я пытаюсь создать динамический сценарий создания базы данных.Создать вид с динамическим Sql

Есть много шагов, и мы часто создаем эту базу данных, поэтому сценарий выглядит примерно так.

DECLARE @databaseName nvarchar(100) = 'DatabaseName' 
EXEC('/*A lot of database creation code built off of @databaseName*/') 

Это хорошо и хорошо, за исключением одного представления, которое мы создаем в этой базе данных.

Проблема, как я понимаю, что это происходит из трех правил в SQL относительно команды EXEC

  1. USE контексты живы только для жизни EXEC
  2. «CREATE VIEW» должен быть первым оператором в пакет запросов
  3. GO на самом деле не является командой SQL и поэтому не разрешен в динамическом sql
  4. В CREATE VIEW вы можете указать только схему.

Итак, вот три вещи, которые я пробовал без успеха.

--1.Results in my view not being created in my database 
EXEC ('USE [' + @databaseName + ']') 
EXEC ('CREATE VIEW') 

--2.Results in a 'CREATE VIEW' must be the first statement in a query batch 
EXEC 
(' 
    USE [' + @databaseName + '] 
    CREATE VIEW 
') 

--3.Results in Incorrect syntax near 'GO' 
EXEC 
(' 
    USE [' + @databaseName + '] 
    GO 
    CREATE VIEW 
') 

--4.Results in 'CREATE/ALTER VIEW' does not allow specifying the database name as a prefix to the object name. 
EXEC ('CREATE VIEW [' + @databaseName + '].[dbo].[ViewName]') 

Любые предложения? Я думаю, что это должно быть распространенным случаем, но Google не смог мне помочь.

ответ

9

Вы можете сделать это с помощью двойных гнездящихся в динамических операторов SQL, то:

begin tran 
declare @sql nvarchar(max) = 
    N'use [AdventureWorks2012]; 
     exec (''create view Test as select * from sys.databases'')'; 

exec (@sql); 

select * from AdventureWorks2012.sys.views 
where name = 'Test' 

rollback tran 
+0

Amazing. Я люблю это. Я проверю очень быстро. –

+1

Вот еще один хороший ответ http://dba.stackexchange.com/a/56956/30584 –

+0

WOW! Я трепетал головой о проблеме в течение 3 дней и никогда не думал об этом! Блестяще, спасибо! –

0

Вместо двойной вложенности, другой подход заключается в создании хранимой процедуры, единственной целью которых является выполняет динамическое SQL

CREATE PROCEDURE [dbo].[util_CreateViewWithDynamicSQL] 
@sql nvarchar(max) 
AS 
BEGIN 
    SET NOCOUNT ON; 
    EXECUTE (@sql) 
END 

Сохраненная процедура выше может быть повторно использована. Каждый раз, когда вам нужно создать представление, просто вызывайте хранимую процедуру и передавайте ей динамический sql.

EXECUTE util_CreateViewWithDynamicSQL 'create view Test as select * from sys.databases' 

Я предпочитаю этот подход, потому что динамический sql достаточно запутан, и добавление двойного гнездования еще более усложняет его.

Смежные вопросы