在功能/存储过程创建时禁用架构检查


17

我正在尝试自动化对SQL Server 2008 R2数据库执行更改的过程。我放置的过程会删除并重新创建我的存储过程和函数,以及运行脚本来更改表/列/数据。不幸的是,其中一个脚本需要首先放置其中一个功能。但是我不能先运行所有存储的proc / function更改,因为它首先依赖于从表/列/数据更改脚本中添加的列。

我想知道是否可以在不通过SQL Server验证函数/ SP定义中使用的列的情况下运行存储过程和函数?我尝试查找,但找不到条件或命令来启用此功能。


听起来您可能只需要重新排列脚本中的对象创建即可。
Thomas Stringer 2012年

@shark这是因为更改脚本需要依赖那里的功能,而这在当时还不是...要做到这一点需要手动干预。我想要更自动的东西。
Brian Mains 2012年

Answers:


20

您可以创建引用尚不存在的对象(例如表和函数)的存储过程。您不能创建引用已存在的对象中尚不存在的列的存储过程。这是延迟名称解析的双刃剑-在某些情况下(并非全部),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在这里有一个有趣的解决方法,但是我没有玩过。


哇,马丁史密斯的骇客非常聪明。我现在会觉得很脏,但是在20多岁的时候会使用它。
John Zabroski

1

您可以创建一个存储过程,该存储过程首先删除或重命名有问题的对象,然后将原始存储过程作为动态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');
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.