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

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

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (4投票s)

2005 年 8 月 15 日

CPOL

2分钟阅读

viewsIcon

26469

downloadIcon

334

一篇介绍如何使用 SQLDMO 的文章。

Sample screenshotSample screenshot

引言

很多人都知道 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。我更奇怪了。我决定从互联网上寻求帮助。我从 www.codeproject.com 下载了许多示例文件进行测试。 结果如下

  1. Santosh Rao (https://codeproject.org.cn/database/sqlsrvenumerator.asp)
    该程序可以正确枚举,但它使用 ODBC 而不是 SQLDMO
  2. Armen Hakobyan (https://codeproject.org.cn/database/ShrinkingSQLServerTransLo.asp)
    该 .exe 文件可以正确枚举,但源代码无法在 vc 6 中编译,等等

我非常仔细地分析了我的代码,我发现函数 ListAvailableSQLServers() 总是每次都能得到正确的数量。但是 spNameList->Item(i) 每次都不能返回正确的结果,所以我甚至猜测数据类型 _bstr_t 有一个错误。我浪费了很多天在 _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 ) ); //

© . All rights reserved.