Как работает SET NOEXEC ON? - PullRequest
       10

Как работает SET NOEXEC ON?

7 голосов
/ 26 февраля 2009

У меня есть следующий код:

-- 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 может не дать часть сообщения "Msg 208".

Затем снова «set noexec on» компилирует код, а не выполняет его. Попытка вставить что-то в таблицу, которая не существует, является ошибкой времени компиляции - я предполагаю. Если это так, то должно появиться сообщение об ошибке «отсутствующий объект».

Теперь позвольте мне рассказать вам о странном поведении, которое я наблюдал. Если я уберу комментарий из строки "- Вывести 'dummy'"

-- 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. Перед запуском этого скрипта.

На этот раз нет сообщения об отсутствующей таблице.

Может кто-нибудь объяснить мне это поведение? Спасибо.

Ответы [ 2 ]

3 голосов
/ 26 февраля 2009

Я бы не ожидал, что будет допустимо использование «set noexec» в условном выражении, как вы это делали, но на самом деле, похоже, оно действительно.

Поведение, по-видимому, связано с тем, что это оператор DDL. Если вы замените вставку оператором печати или простым запросом выбора, сценарий будет работать как положено.

Кстати, если я хочу сделать что-то подобное, я использую следующий подход:

    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, потому что вы избегаете проблем с недействительными объектами.

2 голосов
/ 10 апреля 2014

Я проверил приведенный выше код, и он отлично работает. Это не дает никакого сообщения об ошибке для отсутствующего объекта.

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 включен, поэтому приведенный ниже код будет скомпилирован, но не будет выполнен, следовательно, он не будет передаваться через сообщение об ошибке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...