我有以下代码:
-- start of code
set noexec off
declare @requiredVersion int
declare @currentVersion int
set @requiredVersion = 5
set @currentVersion = 4
if (@currentVersion < @requiredVersion)
begin
print 'Please update your DB to version 5 before running this script.'
set noexec on
end
go
-- print 'Dummy'
insert into tblFooBar(name) values ('AAA')
go
set noexec off
-- end of code
请注意,数据库中不存在表“tblfoobar”。当我运行此代码时,会出现消息:
Please update your DB to version 5 before running this script. Msg 208, Level 16, State 1, Line 1 Invalid object name 'tblFooBar'.
我原以为将noexec设置为ON可能不会给消息的“消息208”部分。
然后再次“设置noexec on”编译代码,不执行它。试图将一些东西插入到一个不存在的表中是一个编译时错误 - 我猜。如果是这种情况,那么应该出现关于“缺失对象”的错误。
现在让我告诉你我观察到的奇怪行为。如果我从“ - 打印'虚拟'”行中删除评论
-- start of code
set noexec off
declare @requiredVersion int
declare @currentVersion int
set @requiredVersion = 5
set @currentVersion = 4
if (@currentVersion < @requiredVersion)
begin
print 'Please update your DB to version 5 before running this script.'
set noexec on
end
go
print 'Dummy'
insert into tblFooBar(name) values ('AAA')
go
并执行代码,我只收到以下消息。
在运行此脚本之前,请将您的数据库更新到版本5.
这次没有关于丢失表的消息。
有人可以向我解释一下这种行为吗?感谢。
答案 0 :(得分:3)
我不会期望在你所做的条件中使用“set noexec”是有效的,但事实上它似乎确实有效。
这种行为似乎与它是一个DDL语句有关。如果使用print语句或简单选择查询替换插入,则脚本将按预期工作。
顺便说一句,如果我想做这样的事情,我会使用以下方法:
create proc tmproc_foobar as CREATE TABLE tblFooBar( name nvarchar(20) ) go if exists ( select 1 from sysobjects where type = 'U' and name = 'tblFooBar' ) exec tmproc_foobar go drop proc tmproc_foobar go
SQL Server允许您使用不存在的对象创建存储过程,因此您可以创建过程,有条件地执行它,然后删除它。这是我有一个很长的升级脚本的方式,有条件地将任何丢失的对象添加到我的数据库。
你也许可以适应这一点。那么你首先不需要noexec,因为你避免了整个无效对象的问题。
答案 1 :(得分:2)
我检查了上面的代码,它运行正常。它没有为丢失的对象提供任何错误消息。
set noexec off
declare @requiredVersion int
declare @currentVersion int
set @requiredVersion = 5
set @currentVersion = 4
if (@currentVersion < @requiredVersion)
begin
print 'Please update your DB to version 5 before running this script.'
set noexec on--> here we are setting NOEXEC on
end
go
-- print 'Dummy'
insert into tblFooBar(name) values ('AAA')
go
set noexec off
-- end of code
由于NOEXEC打开,因此下面的代码将被编译而不会被执行,因此它不会通过任何错误消息。