1

我已经编写了一个更改脚本来更新生产数据库中的架构。我必须删除一个视图并重新创建它们,因为该视图中的一列现在已被删除。

我打算用,

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    
4

1 回答 1

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

于 2013-09-08T10:27:09.347 回答