我编写了一个Change脚本来更新Production DB中的架构。我必须删除一个View并重新创建它们,因为该视图中的一个列现在已被删除。
我打算用,
DECLARE @sql NVARCHAR(MAX);
SET @sql = '<View Definition>';
EXEC sp_executesql @sql;
如果有的话,使用这种方法的缺陷是什么?您会建议哪些替代方案?
我在使用Try catch块的事务下拥有整个脚本。因此,当没有错误时,脚本将被提交,否则回滚。我尝试使用如下的CREATE VIEW命令,但是在引入TRASACTION和TRY-CATCH BLOCKS之后我收到错误。这就是为什么我要使用动态SQL语句 - EXEC sp_executesql 。
错误是“创建视图必须是批处理中的唯一声明”
IF EXISTS ( SELECT * FROM sys.views WHERE name = 'VwViewName')
BEGIN
DROP VIEW VwViewName
END
IF NOT EXISTS ( SELECT * FROM sys.views WHERE name = 'VwViewName')
BEGIN
CREATE VIEW VwViewName
<VIEW DEFINITION>
END
答案 0 :(得分:2)
由于您正在运行架构更新,因此您应该遵守最少的内容,例如
为了使其可重新运行,通常的做法是检查对象是否存在并将其删除,然后再次创建它。
动态SQL不会添加IF
子句具有的任何功能。
例如:
IF EXISTS(SELECT * FROM sys.views WHERE name = 'MyView')
BEGIN
DROP VIEW [MyView]
END
GO
CREATE VIEW MyView AS
SELECT [Columns list ]
FROM [MyTable]
GO
我知道唯一合理dynamic SQL
的案例是,如果您想保留grant
/ deny
,在这种情况下,您可以使用以下语法。
IF NOT EXISTS(SELECT * FROM sys.views WHERE name = 'MyView')
BEGIN
EXEC sp_executesql N'CREATE VIEW MyView AS SELECT 1 AS Dummy'
END
GO
ALTER VIEW MyView AS
SELECT [Columns list ]
FROM [MyTable]
go
GRANT ....
我不会创建Dynamic SQL
来填充我必须在下面的任何脚本中重复名称的几次。恕我直言,部署脚本应尽可能简单。