Обработка ошибок в удаленных хранимых процедурах «сервер-сервер»

При выполнении на клиенте удаленных хранимых процедур и пакетов из локального экземпляра SQL Server могут происходить следующие ошибки, связанные с аварийным завершением инструкций и пакетов.

  • При ошибке аварийного завершения инструкции эта инструкция завершается, но выполнение удаленной хранимой процедуры или пакета продолжается.

  • При ошибке аварийного завершения пакета завершается выполнение всей удаленной хранимой процедуры или всего пакета.

  • Если удаленная хранимая процедура и пакеты выполняются в области блока TRY, то ошибку аварийного завершения пакета можно обработать конструкцией TRY…CATCH.

Поведение удаленных хранимых процедур и пакетов в результате ошибки аварийного завершения инструкции и пакета зависит от того, включена ли инструкция SET XACT_ABORT на локальном сервере.

Инструкция SET XACT_ABORT отключена (OFF)

Если инструкция SET XACT_ABORT отключена (OFF) на локальном сервере, то все ошибки аварийного завершения в удаленной хранимой процедуре передаются с локального сервера клиенту как ошибки аварийного завершения инструкции. Завершается только инструкция, вызвавшая ошибку. Клиент получает сообщения об ошибках, которые соответствуют ошибкам аварийного завершения инструкций. Кроме того, если удаленная хранимая процедура выполняется вплоть до завершения, то функция @@ERROR возвращает 0. Если ошибка произошла в области блока TRY, то выполнение продолжается, и блок CATCH не вызывается.

Все ошибки аварийного завершения пакета в удаленной хранимой процедуре передаются локальным сервером клиенту. Инструкция EXECUTE, вызвавшая удаленную хранимую процедуру, завершается, но выполнение пакета или удаленной хранимой процедуры, содержавших инструкцию EXECUTE, продолжается. Таким образом, функция @@ERROR возвращает код ошибки, с которой завершилась удаленная хранимая процедура, а возвращаемое значение хранимой процедуры будет равно NULL. Если удаленная хранимая процедура, вызвавшая ошибку, выполняется в области блока TRY на локальном сервере, то эта ошибка вызывает передачу управления в блок CATCH со сведениями о последней ошибке на удаленном сервере.

При диагностике ошибок выполните удаленную хранимую процедуру внутри блока TRY конструкции TRY…CATCH. При ее неуспешном завершении выполнение переходит к соответствующему блоку CATCH на локальном сервере с данными о последней ошибке на удаленном сервере. Если удаленная хранимая процедура завершается успешно, то выполнение продолжается внутри блока TRY на локальном сервере, поэтому можно использовать ее возвращаемое значение.

Если же удаленная хранимая процедура выполняется вне области блока TRY, просмотрите значение @@ERROR в конце удаленной хранимой процедуры, чтобы определить ее состояние по завершении. Если значение @@ERROR равно 0, то удаленная хранимая процедура завершилась успешно и можно использовать ее возвращаемое значение. Если значение @@ERROR не равно 0, то удаленная хранимая процедура завершилась неуспешно, и ее возвращаемое значение использовать нельзя.

Инструкция SET XACT_ABORT включена (ON)

Если инструкция SET XACT_ABORT включена (ON) на локальном сервере, то этот параметр переносится на связанный сервер. Все ошибки аварийного завершения инструкций и пакетов в удаленной хранимой процедуре преобразуются в ошибки аварийного завершения пакета на локальном сервере. Поэтому выполнение пакета или удаленной хранимой процедуры, вызвавшей удаленную хранимую процедуру, завершается вместе с удаленной хранимой процедурой. Если удаленная хранимая процедура, которая создает ошибку, выполняется в области блока TRY на локальном сервере, то ошибка вызывает передачу управления в блок CATCH со сведениями о последней ошибке на удаленном сервере.

Если удаленная хранимая процедура выполняется вне области блока TRY, то невозможно проанализировать значение @@ERROR и определить наличие ошибки пакета, поскольку инструкция, следующая за инструкцией EXECUTE, не выполняется. Таким образом, удаленную хранимую процедуру следует выполнять внутри блока TRY конструкции TRY…CATCH. При ее неуспешном завершении выполнение переходит к соответствующему блоку CATCH на локальном сервере с данными о последней ошибке на удаленном сервере. Если удаленная хранимая процедура завершается успешно, то выполнение продолжается внутри блока TRY на локальном сервере, поэтому можно использовать возвращаемое значение удаленной хранимой процедуры.

RAISERROR и TRY…CATCH

Вызов оператора RAISERROR с уровнем серьезности ошибки менее 20 из удаленной хранимой процедуры вызывает ошибку аварийного завершения инструкции на удаленном сервере. Конструкция TRY…CATCH на локальном сервере обрабатывает только ошибки аварийного завершения удаленного пакета. Если удаленная хранимая процедура вызывает оператор RAISERROR с уровнем серьезности менее 20 и эта удаленная хранимая процедура находится в области блока TRY на локальном сервере, то RAISERROR не передает управление блоку CATCH конструкции TRY…CATCH. Однако оператор RAISERROR с уровнем серьезности ошибки 20 или более на удаленном сервере разрывает соединение, и выполнение на локальном сервере передается блоку CATCH.