我正在尝试创建一个动态数据库创建脚本。
有很多步骤,我们经常创建这个数据库,所以脚本看起来像这样。
DECLARE @databaseName nvarchar(100) = 'DatabaseName'
EXEC('/*A lot of database creation code built off of @databaseName*/')
除了我们在此数据库中创建的一个视图外,这一切都很好。
我理解的问题源于SQL中有关EXEC命令的三条规则
所以这里有三件事我没有成功。
--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]')
有什么建议吗?我认为这应该是一个常见的用例,但谷歌无法帮助我。
答案 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足够混乱,并且添加双嵌套使其进一步复杂化。