SQL.RU
 client/server technologies
 Главная | Документация | Статьи | Книги | Форум | Блоги | Опросы | Гостевая | Рассылка | Работа | Поиск | FAQ |

Определение недоступности линкед-сервера

ПУБЛИКАЦИИ  

Автор: Глеб Уфимцев. г.Москва. 4 окт 2005г.

Как заставить MSSQL сервер продолжить исполнение батча или процедуры дальше, несмотря на критическую ошибку. Или как в T-SQL проверить доступность линкед-сервера.

Если у нас стоит задача в батче (или внутри процедуры) проверить доступность прилинкованного сервера, чтобы ниже по коду принять решение, использовать ли запрос к нему или обратиться к другому источнику данных, то здесь нас поджидает засада. Только успешная попытка выполнить к нему какой-либо запрос даст уверенность в его полной доступности, но любое обращение к недоступному линкед-серверу прервет исполнение батча. Существует решение использовать для проверки системные хранимые процедуры OLE-автоматизации (sp_OACreate, sp_OA_Method, …), посредством которых к текущему серверу открывается соединение объектами ADO, исполняется запрос через линкед-сервер и, по наличию ошибки, возвращается ответ. Решение замечательное и вполне работает, но имеет ряд недостатков:

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

  • Приходится явно указывать пароль при SQL-авторизации.

  • Для Windows-авторизации авторизовываться будет учетная запись SQL-сервера, а не текущего пользователя, что не гарантирует успех такого соединения.

  • Не дает решения "в целом", чтобы решение можно было распространить на другой случай, где тоже требуется продолжить батч независимо от ошибки.

В связи с этим было изобретено более удобоваримое решение (конечно, не претендующее на исключительность). В процессе экспериментов выяснилось, что если критичный запрос пропустить через другой, заведомо доступный линкед-сервер, то батч не прервется, хотя ошибка будет та же самая, и можно даже получить значение @@ERROR для анализа. Нет причин, почему бы нам не сделать этот второй линкед-сервер как залинкованый исходный сервер сам к себе.

Разберем этот вариант на примере. Исходные данные:

    Текущий сервер - SERVER1
    Прилинкованный сервер, доступность которого нам нужно будет проверять - ну пусть будет просто LINKED

Убеждаемся в недоступности (LINKED погашен на самом деле):

SELECT * FROM LINKED.master.dbo.sysusers SELECT @@ERROR

Получаем ошибку:

Msg 17, Level 16, State 1, Line 1 SQL Server does not exist or access denied.

И не получаем значение @@ERROR так как батч прервался.

Тогда действуем, как запланировано. На исходном сервере SERVER1 регистрируем новый линкед-сервер, причем тот же самый SERVER1, только имя линкед-сервера задаем "LOOPBACK", и убеждаемся в его работоспособности. Главное, чтобы название прилинкованного сервера было отличным от родного имени сервера, которого он представляет на самом деле. Этого можно добиться различными путями. Самый простой из них - в Client Network Utility зарегистрируем алиас "LOOPBACK" на сервер "SERVER1" и в настройках линкед-сервера укажем сервер LOOPBACK. Через этот сервер и пропустим запрос.

EXEC LOOPBACK...sp_executesql N'SELECT * FROM LINKED.master.dbo.sysusers' SELECT @@ERROR

Получили приятный ответ:

Msg 17, Level 16, State 1, Line 1 SQL Server does not exist or access denied. ----------- 17 (1 row(s) affected)

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

[В начало]

Автор: Глеб Уфимцев  2005г.

Rambler's Top100 Рейтинг@Mail.ru  Administrator: Обратная связь 
Copyright: SQL.Ru 2000-2013