65.9K
CodeProject 正在变化。 阅读更多。
Home

如何通过 LAN 枚举 SQL Server(使用 SQLDMO)

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (2投票s)

2005年8月25日

2分钟阅读

viewsIcon

45458

downloadIcon

776

一篇关于如何使用SQLDMO枚举SQL Server实例的文章。

 

引言

许多人都知道可以使用SQLDMO枚举SQL Server,但可能很少人知道在使用SQLDMO时存在一个问题。如果在程序中没有正确使用SQLDMO,你可能会发现某些SQL Server数据库无法枚举。

  1. #import "C:\Program Files\Microsoft SQL Server\80\Tools\Binn\Resources\1033\sqldmo.rll" no_namespace
  2. #import "C:\Program Files\Microsoft SQL Server\80\Tools\Binn\Resources\1033\sqldmo.rll"

方法1可以得到右侧图片所示的结果。方法2可以得到左侧图片所示的结果。你可能会注意到,左侧图片缺少一台SQL Server机器。

背景

两周前,我编写了一个VC程序来枚举局域网中的所有SQL Server实例。像大多数人一样,我使用方法1编写了程序。程序似乎运行正常。但我发现一台安装了SQL Server的机器无法列出。这很奇怪。然后我用VB编写了它,它可以枚举所有SQL Server实例。我又用ODBC编写了另一个程序,它可以枚举每个SQL Server。我越来越惊讶。我决定从互联网上寻求帮助。我搜索了CodeProject的示例文件进行测试。结果列表如下:

  1. Rashid Thadha使用SQL DMO枚举SQL Server

    与我的情况一样,无法枚举所有实例。

  2. Santosh RaoSQL Server和数据库枚举器

    该程序可以正确枚举,但它使用的是ODBC而不是SQLDMO。

  3. Armen Hakobyan使用SQL-DMO收缩SQL Server事务日志

    .exe文件可以正确枚举,但是源代码无法在VC 6中编译。

等等……

我非常仔细地分析了我的代码,我发现函数ListAvailableSQLServers()每次都能得到正确的结果。但是spNameList->Item(i)并不总是返回正确的结果。所以我甚至怀疑数据类型_bstr_t有bug。我在_bstr_t上浪费了很多时间。我当然没有收获,我很失望。

偶然的机会,我用方法2重写了我的程序,新的程序可以枚举所有SQL Server实例。我太高兴了,立刻写了这篇文章,让其他人分享我的喜悦。

使用代码

   // if you use method 1,then you shold write as 
   try
   {
     _SQLServerPtr spSQLServer;
     
     HRESULT hr2 = spSQLServer.CreateInstance(__uuidof(SQLServer));
     if (SUCCEEDED(hr2))
     {
        try
        {
           // Get the Application Ptr
           long lServerCount;
           _ApplicationPtr pApplication = spSQLServer->GetApplication();
           if (pApplication) 
           {
                NameListPtr pServerNameList = 
                     pApplication->ListAvailableSQLServers();
                if (pServerNameList)
                { 
                    lServerCount = pServerNameList->Count;
                    for (long  i=0;  i <  lServerCount; i++)
                    {
                        _bstr_t bstrValue(pServerNameList->Item( i ));
                         CString sName((LPCSTR)bstrValue);
                         if (!sName.IsEmpty())
                                m_ctlComboBox.AddString(sName);
                    }
                }
            }
            pApplication = NULL;
                
            spSQLServer.Release();
        }
        catch (_com_error e)
        {
             spSQLServer.Release();
        }
    }
    else
    {
        AfxMessageBox("Create Error.");
    }
  }
  catch (_com_error e)
  {
     AfxMessageBox("Error");
  }
 
  // if you use method 2,the you should write as 
  SQLDMO::_ApplicationPtr spApplication = NULL;
  SQLDMO::_SQLServerPtr spSQLServer;
  HRESULT hr = spSQLServer.CreateInstance(__uuidof(SQLDMO::SQLServer));
  if (FAILED(hr))
  {
      AfxMessageBox("CreateInstance() error!");
      return;
  }
  spApplication =spSQLServer->GetApplication();
  SQLDMO::NameListPtr spNameList = spApplication->ListAvailableSQLServers();
  LONG lCount = spNameList->GetCount();
  for ( LONG l = 1; l <= lCount; l++ )
      m_ctlComboBox.AddString( (LPCTSTR)spNameList->Item( l ) );

历史

  • 2005-08-25 - 文章首次发表。
© . All rights reserved.