使用动态Sql创建视图

时间:2014-01-16 21:35:30

标签: sql-server tsql dynamic-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上,您只能指定为Schema。
  5. 所以这里有三件事我没有成功。

    --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]')
    

    有什么建议吗?我认为这应该是一个常见的用例,但谷歌无法帮助我。

2 个答案:

答案 0 :(得分:10)

您可以通过双重嵌套动态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

答案 1 :(得分:1)

另一种方法是创建一个存储过程,而不是双重嵌套,它的唯一目的是执行动态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足够混乱,并且添加双嵌套使其进一步复杂化。