Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    « Parsing the FullName field to individual componentsChanging a SQL Server Database Owner »
    comments

    I have a bunch of linked servers to SQL Servers and also to Sybase ASE Servers ON AIX machines. There are some interesting things that can happen. For example if you type the name of the object or the linked server itself wrong, you can't trap this..... or can you?

    Let's take a look. Open up SSMS and connect to your local instance. Now create a linked server named TestLinkedServer which points to the local server. The code to do that is below.

    1. EXEC master.dbo.SP_ADDLINKEDSERVER @server = N'TestLinkedServer',
    2.                                    @srvproduct=N'',
    3.                                    @datasrc='(local)',
    4.                                    @provider='SQLNCLI'



    Now we can do a small test, run the following code

    1. SELECT * FROM OPENQUERY(TestLinkedServer,'select count(*) from tempdb..sysobjects')

    That should return an integer.

    If we try something more interesting like a division by zero, will it get trapped?

    1. BEGIN TRY   
    2.      SELECT * FROM OPENQUERY(TestLinkedServer,'select 1/0')
    3. END TRY
    4.  
    5. BEGIN CATCH
    6.      
    7.     PRINT ERROR_MESSAGE()
    8.     PRINT  ERROR_NUMBER()
    9. END CATCH
    10. PRINT 'TEST'

    Divide by zero error encountered.
    8134
    TEST

    Yes, that worked just as expected.
    Now what do you think will happen if we change the table name from sysobjects to sysobjects2? Let's run it and see

    1. BEGIN TRY   
    2.      SELECT * FROM OPENQUERY(TestLinkedServer,'select count(*) from tempdb..sysobjects2')
    3. END TRY
    4.  
    5. BEGIN CATCH
    6.      
    7.     PRINT ERROR_MESSAGE()
    8.     PRINT  ERROR_NUMBER()
    9. END CATCH
    10. PRINT 'TEST'

    OLE DB provider "SQLNCLI10" for linked server "TestLinkedServer" returned message "Deferred prepare could not be completed.".
    Msg 8180, Level 16, State 1, Line 1
    Statement(s) could not be prepared.
    Msg 208, Level 16, State 1, Line 1
    Invalid object name 'tempdb..sysobjects2'.

    Ouch it blew up on us and never made it to the print statement.

    How about if we use TestLinkedServer2 instead of TestLinkedServer?

    1. BEGIN TRY   
    2.      SELECT * FROM OPENQUERY(TestLinkedServer2,'select count(*) from tempdb..sysobjects')
    3. END TRY
    4.  
    5. BEGIN CATCH
    6.      
    7.     PRINT ERROR_MESSAGE()
    8.     PRINT  ERROR_NUMBER()
    9. END CATCH
    10. PRINT 'TEST'

    Msg 7202, Level 11, State 2, Line 4
    Could not find server 'TestLinkedServer2' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.

    Same problem, blows up and never makes it to the print statement. What if we take the last two examples and wrap them inside an exec statement?

    1. BEGIN TRY   
    2.      exec( 'SELECT * FROM OPENQUERY(TestLinkedServer,''select count(*) from tempdb..sysobjects2'')')
    3. END TRY
    4.  
    5. BEGIN CATCH
    6.      
    7.     PRINT ERROR_MESSAGE()
    8.     PRINT  ERROR_NUMBER()
    9. END CATCH
    10. PRINT 'TEST'

    OLE DB provider "SQLNCLI10" for linked server "TestLinkedServer" returned message "Deferred prepare could not be completed.".
    Invalid object name 'tempdb..sysobjects2'.
    208
    TEST

    That caught the exception and TEST was printed

    1. BEGIN TRY   
    2.      exec( 'SELECT * FROM OPENQUERY(TestLinkedServer2,''select count(*) from tempdb..sysobjects'')')
    3. END TRY
    4.  
    5. BEGIN CATCH
    6.      
    7.     PRINT ERROR_MESSAGE()
    8.     PRINT  ERROR_NUMBER()
    9. END CATCH
    10. PRINT 'TEST'

    Could not find server 'TestLinkedServer2' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.
    7202
    TEST

    Beautiful, Even using a non existent linked server name is caught when using it inside an EXEC statement.

    As you can see it is possible to trap a problem with linked servers if you wrap it inside an Exec statement which you could not trap otherwise. One thing you can't trap however is a timeout.

    Here are some of the error messages I trapped on my boxes

    Cannot fetch a row from OLE DB provider "MSDASQL" for linked server "Test".
    Cannot initialize the data source object of OLE DB provider "MSDASQL" for linked server "Test".
    The OLE DB provider "MSDASQL" for linked server "Test" could not INSERT INTO table "[MSDASQL]".
    The OLE DB provider "MSDASQL" for linked server "Test" reported an error committing the current transaction.

    Hope you learned something and hopefully this will help you in your troubles with linked servers




    *** Remember, if you have a SQL related question, try our Microsoft SQL Server Programming forum or our Microsoft SQL Server Admin forum

    About the Author

    User bio imageDenis has been working with SQL Server since version 6.5. Although he worked as an ASP/JSP/ColdFusion developer before the dot com bust, he has been working exclusively as a database developer/architect since 2002. In addition to English, Denis is also fluent in Croatian and Dutch, but he can curse in many other languages and dialects (just ask the SQL optimizer) He lives in Princeton, NJ with his wife and three kids.
    Social SitingsTwitterFacebookLinkedInHomePageFlickrLTD RSS Feed
    2400 views
    Instapaper

    No feedback yet

    Leave a comment


    Your email address will not be revealed on this site.

    Your URL will be displayed.
    (Line breaks become <br />)
    (Name, email & website)
    (Allow users to contact you through a message form (your email will not be revealed.)