作为模式更改脚本中的存储过程的视图

时间:2013-09-08 00:09:24

标签: sql sql-server tsql database-schema

我编写了一个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    

1 个答案:

答案 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来填充我必须在下面的任何脚本中重复名称的几次。恕我直言,部署脚本应尽可能简单。