Read more: http://www.blogsmonetize.com/2010/10/how-to-use-syntax-highlighter-3083-in.html#ixzz1DHzvEgBA

Monday, June 9, 2008

Testing the Linked server connectivity From SQL server 2005

Have you ever encountered a scenario in SQL Server 2000 where you want to test the connectivity of a linked server configuration via TSQL? This was not possible easily and best handled from client side. But we have now a system stored procedure "sp_testlinkedserver" in SQL Server 2005 that allows you to test linked server connection. This stored procedure takes a linked server name as parameter, tests the connectivity and returns 0 for success & 1 for failure. You can find more details about this stored procedure in the SQL Server 2005 Books Online. Here is how a sample call can look like:

declare @srvr nvarchar(128), @retval int;
set @srvr = 'my_linked_srvr';
begin try
exec @retval = sys.sp_testlinkedserver @srvr;
end try
begin catch
set @retval = sign(@@error);
end catch;
if @retval <> 0
raiserror('Unable to connect to server. This operation will be tried later!', 16, 2 );
The reason for the try...catch block is left as an exercise to readers!

Due to lack of exception handling and implementation of OPENQUERY/OPENROWSET/OPENDATASOURCE interfaces it is not possible to do it cleanly. The afore-mentioned interfaces remain the same in SQL Server 2005 also and they perform their validation at compile-time itself. So for example, if the linked server name is incorrect or the parameter to OPENROWSET is invalid you will get an error immediately. You cannot capture such errors within TRY...CATCH also. You need to enclose it in dynamic SQL so it can be caught in the same batch as the TRY...CATCH. EX:
-- below will fail at compile-time itself
-- so the try..catch never executes
begin try
select * from openquery(missing_server, 'select * from sys.tables')
end try
begin catch ... end catch

-- using dynamic sql will help since the query
-- is evaluated only when the dynamic SQL statement is executed
begin try
exec('select * from openquery(missing_server, ''select * from sys.tables'')')
end try
begin catch ... end catch
This also holds true in SQL Server 2000. Compare code below:
select * from openquery(some_servr, 'select 1')
if @@error <> 0
begin
print 'Error'
end
go
exec('select * from openquery(some_servr, ''select 1'')')
if @@error <> 0
begin
print 'Error'
end
So the bottom-line is that you could use dynamic SQL to run the test statement against remote server and catch any errors. Now, as for your question about different domains there is lot of complexity involved depending on how you want to establish the connection. If you are using SQL logins then it is straight forward assuming the firewall or network settings allow communication between the servers. In case of Windows authentication, you may have to enable constrained delegation (Windows Server 2003) or security delegation depending on service account configurations and from where the clients connect. See BOL for discussion on these topics.

No comments: