Konfiguruję zadanie, aby przejrzeć listę połączonych serwerów i wykonać określone zapytanie dla każdego z nich. Próbuję wykonać kwerendę w bloku TRY-CATCH, więc jeśli występuje problem z jednym konkretnym serwerem, mogę go zarejestrować, a następnie kontynuować z innymi serwerami.
Zapytanie, które wykonuję wewnątrz pętli, wygląda mniej więcej tak:
BEGIN TRY
SELECT *
FROM OPENQUERY([server1], 'SELECT 1 AS c;');
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER(), ERROR_MESSAGE();
END CATCH;
PRINT 'We got past the Catch block!';
Jeśli wystąpi problem z połączeniem z serwerem, kod po prostu zawiedzie natychmiast i nie zostanie przesłany do CATCH
bloku. Jeśli serwer łączy się, ale w rzeczywistym zapytaniu wystąpił błąd, np. Podziel przez zero, jest to wychwytywane zgodnie z oczekiwaniami CATCH
bloku.
Na przykład utworzyłem serwer połączony z nazwą, o której wiem, że nie istnieje. Wykonując powyższe otrzymuję:
OLE DB provider "SQLNCLI" for linked server "nonserver" returned message
"Login timeout expired".
OLE DB provider "SQLNCLI" for linked server "nonserver" returned message
"An error has occurred while establishing a connection to the server.
When connecting to SQL Server 2005, this failure may be caused by the
fact that under the default settings SQL Server does not allow remote
connections.".
Msg 53, Level 16, State 1, Line 0
Named Pipes Provider: Could not open a connection to SQL Server [53].
Przeczytałem BOL TRY-CATCH
i wiem, że nie będzie on wychwytywał błędów poziomu 20+, które przerywają połączenie, ale wydaje się, że tak nie jest (tylko poziom 16).
Czy ktoś wie, dlaczego te błędy nie są wychwytywane poprawnie?