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





4.00/5 (2投票s)
2005年8月25日
2分钟阅读

45458

776
一篇关于如何使用SQLDMO枚举SQL Server实例的文章。
引言
许多人都知道可以使用SQLDMO枚举SQL Server,但可能很少人知道在使用SQLDMO时存在一个问题。如果在程序中没有正确使用SQLDMO,你可能会发现某些SQL Server数据库无法枚举。
#import "C:\Program Files\Microsoft SQL Server\80\Tools\Binn\Resources\1033\sqldmo.rll" no_namespace
#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的示例文件进行测试。结果列表如下:
- Rashid Thadha:使用SQL DMO枚举SQL Server。
与我的情况一样,无法枚举所有实例。
- Santosh Rao:SQL Server和数据库枚举器。
该程序可以正确枚举,但它使用的是ODBC而不是SQLDMO。
- 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 - 文章首次发表。