HOWTO: 如何枚举本地网络中的 SQL Server 服务器
周融 (C) 2006 保留所有权利。
本文内容
由于一些软件设计上的需要,开发人员可能需要枚举本地网络中的可用 Microsoft SQL Server 服务器,本文提供了一些快捷的方法和思路,以帮助开发人员有效的提高生产效率。
本文所涉及到的内容可能需要开发人员了解一下一部分技术:LAN、域、ActiveX、COM、Win32 API、端口、Windows NT 服务器、SQL Server 分布式管理对象、自动化。
在本文中:
· SQL Server 服务器概述
· 什么样的计算机可以被有效的枚举
· 使用 SQLDMO 枚举 SQL Server 服务器
· 新的思路
· 结论
一、SQL Server 服务器概述
Microsoft(R) SQL Server(TM) 是一种高效的数据库服务器,它最开始基于 Sybase 而设计,10 多年来,SQL Server 一致被众多大中型企业采用,并为许多开发人员所认可和接受。
SQL Server 自 6.5 一来就开始支持基于群集的部署方式,因此,在一个本地网络(LAN, Local Area Network)中可以部署多个 SQL Server 服务器协同工作(而并非多个 SQL Server 实例)。但系统管理员为此付出的管理成本也会相应增加,例如在一个巨大的连锁超市的 IT 解决方案中,需要实时监控网络中的所有 SQL Server 服务器的运行状态,如果服务器有效运行,则与之交换信息,否则不予连接。如果没有有效的方法枚举这些运行的 SQL Server 服务器,而应用程序可能会为每一个网络中的计算机建立连接以便查找可用的 SQL Server,这样就可能会大幅度降低生产效率。
SQL Server 提供了一些途径来达到以上目的。首先,SQL Server 基于 Windows 服务而设计,在 Windows 运行过程中,SQL Server 服务(称之为 "MSSQLServer")状态为启动,当 SQL Server 不可用时,SQL Server 服务状态为停止或禁用。其次,SQL Server 支持 RPC 调用,这意味着您可以通过远程访问来管理可用的 SQL Server 服务器,每一个可用的 SQL Server 都提供一个可用端口,SQL Server 监听程序使用这个端口跟踪并处理远程的 SQL Server 请求。
当然,现在的 SQL Server 2005 提供了更加丰富的通信方式,除了命名管道、TCP/IP、NetBIOS 外,还提供基于 .NET 的 SharedMemory 通信,这将更有利于 CLR 和 SQL Server 的集成和提高处理大批量数据的能力。
二、什么样的计算机可以被有效地枚举
通常,Microsoft SQL Server 服务器部署在 Windows NT 服务器上,为了便于通信,在启用了 Windows 防火墙的服务器需要配置 Windows 防火墙例外,以便启用 SQL Server 通信端口;如果这台服务器满足以下条件,则可以被正确的枚举:
· 运行在本地工作组或域上的计算机
· SQL Server 端口没有被禁用
· SQL Server 是以下版本之一:Microsoft SQL Server 7.0, SQL Server 2000(所有版本), SQL Server 2005(所有版本)。
· 计算机运行下列操作系统之一:Microsoft Windows NT 4.0, Windows 2000, Windows Server 2003, Windows Server codename "Longhorn"。
枚举 SQL Server 服务器可能需要网络节点访问权限(Active Directory 计算机成员权限)。
三、使用 SQLDMO 枚举 SQL Server 服务器
SQL Server 分布式管理对象(SQLDMO, SQL Distributed Management Objects)提供了可用的方案,可以十分方便的枚举 SQL Server 服务器,这些方案包含在 SQLDMO 的可发行 DLL 中。
为了获得这些功能,针对不同的语言可能会有不同的方式,由于 SQLDMO 提供的是一个 COM 库,不能被 ActiveX 所包装,因此,必须引入 DLL 中这些类库的声明才能在代码中使用 SQLDMO。
SQL Server 2000 提供了两个版本的 SQLDMO DLL,它们的版本分别为 8.0 和 8.5,8.5 版本的 DLL 是 SQL Server Service Pack 3 才提供的,这些 DLL 位于 %Program Files%/Microsoft SQL Server/xx/binn 中。xx 代表 SQL Server 版本,如果您安装的是 SQL Server 2000,则应选择 80,如果是 SQL Server 2005,则选择 90。
下面针对 VB 和 Delphi 分别介绍如何利用 SQLDMO 枚举 SQL Server 服务器,请参见下面的代码。
首先需要您在您的项目中创建一个窗体,将一个 ListView 放入窗体中以便显示服务器列表。
[Microsoft Visual Basic 6.0]













[Microsoft Visual Basic 2005]












[Delphi]
procedure TForm1.ClickOk(Sender: TObject);
var
sqlApp: Application;
names: NameList;
i: Integer;
begin
// TODO
Screen.Cursor := crHourGlass;
sqlApp := CoApplication.Create;
names := sqlApp.ListAvailableSQLServers;
if names.Count <> 0 then
begin
lvwMain.Items.Clear;
for i := 0 to names.Count - 1 do
begin
lvwMain.Items.Add.Caption := names.Item(i);
end;
end;
Screen.Cursor := crDefault;
end;
代码中使用了 SQLDMO.Application 对象,该对象具备 ListAvailableSQLServers 方法,可以枚举满足条件(参加第二节)的所有可用 SQL Server 服务器。
注意:在执行这些代码之前,您需要将 SQLDMO 类型库导入到项目中。
对于 Visual Basic:打开 Visual Studio 2005,单击“项目” -> “添加引用...”,并选择 COM 对象选项卡,再单击“Microsoft SQLDMO Object library”。
对于 Delphi,打开 Borland Delphi 7,单击“项目” -> “导入类型库...”,并选择“Microsoft SQLDMO Object library”。注意,导入类型库后可能无法编译,请将错误行的 property ID... 改为 property ID2... 后重新编译。
这种方法枚举数据库的优点是:
· 可以枚举网络上的所有可用 SQL Server 服务器
· 速度快,效率高
· 对权限的要求比较低
· 不依赖终端服务
缺点是:
· 需要 SQL Server 客户端的支持
· 不能枚举非本地网络中的 SQL Server
· 不能枚举本地网络中的非 Windows NT 服务器的 SQL Server 部署。
· 每次枚举 SQL Server 有一定的延时,服务启动后,可能需要 1 到 2 分钟才能被检测到。
四、新的思路
我提供一些新的枚举思路,仅用开发人员参考。
1、利用 NET START
nET START 命令可以枚举计算机上的所有已经启动的服务,如果服务列表中存在 MSSQLServer,则表明 SQL Server 已经启动。但 NET START 仅能枚举本地计算机上的服务,如果需要枚举远程计算机,则需要终端服务,这可能会降低效率。
2、使用 ADO 或 ADO.NET
因为 ADO 可以创建 SqlConnection 而与 SQL Server 连接,如果调用该 SqlConnection 实例的 Open 方法出现异常,则证明该服务器不可用。这种方法最简单和容易接受,但由于需要至少两次访问远程计算机,加上需要枚举每一台网络上的计算机,所以效率也不高。开发人员往往比较喜欢使用这种方式。
3. 通过 Windows 事件日志
Windows 事件日志记录了 Windows 每一个服务的状态,如果查找 Windows 事件日志,发现与当前事件最接近的记录中存在对 MSSQLServer 停用的描述,则表示该 SQL Server 服务器已不可用。这种方法效率最高,但访问 Windows 事件日志需要一定的技术,并且需要更高的权限和终端服务的支持。
五、结论
通过本文的介绍,您或许已经掌握了枚举 SQL Server 服务器的方法和思路,需要指出的是,本文提供的各种枚举方法都有优劣,需要根据应用程序不同的应用范围和目的决定使用哪一种枚举方式。我非常欢迎大家一同来讨论如何才能更高效的达到本文提出的目的,您也可以亲自动手试一试编写本文中所提供的代码。