我正在尝试自动化对SQL Server 2008 R2数据库执行更改的过程。我放置的过程会删除并重新创建我的存储过程和函数,以及运行脚本来更改表/列/数据。不幸的是,其中一个脚本需要首先放置其中一个功能。但是我不能先运行所有存储的proc / function更改,因为它首先依赖于从表/列/数据更改脚本中添加的列。
我想知道是否可以在不通过SQL Server验证函数/ SP定义中使用的列的情况下运行存储过程和函数?我尝试查找,但找不到条件或命令来启用此功能。
我正在尝试自动化对SQL Server 2008 R2数据库执行更改的过程。我放置的过程会删除并重新创建我的存储过程和函数,以及运行脚本来更改表/列/数据。不幸的是,其中一个脚本需要首先放置其中一个功能。但是我不能先运行所有存储的proc / function更改,因为它首先依赖于从表/列/数据更改脚本中添加的列。
我想知道是否可以在不通过SQL Server验证函数/ SP定义中使用的列的情况下运行存储过程和函数?我尝试查找,但找不到条件或命令来启用此功能。
Answers:
您可以创建引用尚不存在的对象(例如表和函数)的存储过程。您不能创建引用已存在的对象中尚不存在的列的存储过程。这是延迟名称解析的双刃剑-在某些情况下(并非全部),SQL Server为您带来了疑问的好处。请参阅Erland的想法,SET STRICT_CHECKS ON;
以获取有关此功能的工作场所及其损坏的地方的一些想法:
http://www.sommarskog.se/strict_checks.html
(以及他想要的方式与您所追求的相反—您想要允许任何东西都可以编译,而不论它是否存在,并且他希望检查每一个列或表。)
没有像SET DEFERRED_NAME_RESOLUTION OFF;
要求这样的设置:
http://connect.microsoft.com/sql/127152
而且没有像这样的设置IGNORE ALL_RESOLUTION;
。
您可以通过几种方式解决此问题,包括:
(a)在受影响的存储过程中使用动态SQL。
(b)构建一个CREATE PROCEDURE
没有任何内容的存根,然后运行脚本的其余部分,然后运行ALTER PROCEDURE
具有真实主体的存根(本质上,分两个阶段部署过程)。
(c)使您的部署工具更智能地了解操作顺序。如果表更改需要功能的存在,则最后编写这些更改的脚本。像RedGate的SQL Compare这样的模式比较工具非常适合按适当的依赖顺序为您生成脚本。您没有提到您使用的是什么工具,但是如果没有使用它...
(d)Martin Smith在这里有一个有趣的解决方法,但是我没有玩过。
您可以创建一个存储过程,该存储过程首先删除或重命名有问题的对象,然后将原始存储过程作为动态SQL运行。这样,您不必重写实际的存储过程即可使用动态SQL。
下面的代码运行一个存储过程,该存储过程引用了尚不存在的列(Expense_Super_Compare)
IF OBJECT_ID('Expense_Super_Compare_Results', 'U') IS NOT NULL
BEGIN
EXEC('DROP TABLE Expense_Super_Compare_Results');
END
exec('exec dbo.Expense_Super_Compare');