我用ado连接数据库,希望能动态的连接数据库服务器。但是我怎样才能知道本网中服务器的IP呀?

解决方案 »

  1.   

    ZT:标题:如何能得到本LAN内的SQL服务器列表?iamfly (2000-12-26 19:51) 425726 
    看到一本SQL7的书里说到在VB里可以用DMO得到本网段内有哪几台SQL服务器正在运行:)
    不过DMO是和SQL的版本有关,而且,在DELPHI里找了下,没找到和DMO有关的东东:(
    哪位能说说的?谢了:) 
    zhuhuan (2000-12-26 21:21) 
    SQL-DMO是一个COM组件,你必须import type libary,就会生成一个pas
    文件,里面是所有接口的声明,这样就可以使用DMO对象了,不过如何查找SQL SERVER我
    不清楚,估计是在所有机器上都CONNECT一下出错就表示没有,这样就可以找到所有的
    server了,如果知道什么方法不如贴出来看一下,在DELPHI里用COM实现和用VB没什么区别 
    iamfly (2000-12-26 21:27) 
    我明天试试看,做成功了就贴出我的代码来:) 
    sportsman (2000-12-27 9:24) 
    想知道 
    Iknow (2000-12-27 9:33) 
    NET_API_STATUS NetServerEnum(
      LPWSTR servername,
      DWORD level,           
      LPBYTE *bufptr,   
      DWORD prefmaxlen,    
      LPDWORD entriesread,   
      LPDWORD totalentries,    
      DWORD servertype,   //SV_TYPE_SQLSERVER  
      LPWSTR domain,         
      LPDWORD resume_handle  );参考:MSDN 
    iamfly (2000-12-27 9:58) 
    用SQL DMO麻烦,我把这个DMO东东INSTALL进去后,再把它的COMPONENT放上我的FORM,
    发现在我的程序里原来的APPLICATION不能用了:(  截止到目前为止,我还没想到怎么去做,
    不过,IKnow说的这个API函数我去查了下,可以:)正在试验过程中,OK了后再分分吧,
    哈哈:D
     
    li_tj (2000-12-27 10:4) 
    关注此题 
    iamfly (2000-12-27 13:59) 
    关于NETSERVERENUM,DELPHI并没有它的声明文件:(
    应该是在NETAPI。DLL里的,莫非我又要想用REGISTERSERVICEPROCESS一样的来调用它:(
    麻烦,先试试吧。
    BTW 有谁用过这个API函数的?烦请告诉一声,谢了^_^ 
    温柔一刀 (2000-12-27 15:21) 
    用SQLDOM最容易:procedure TForm1.Button1Click(Sender: TObject);
    var
       SQLServer:Variant;
       ServerList:Variant;
       i,nServers:integer;
       sRetValue:String;
    begin  SQLServer := CreateOleObject('SQLDMO.Application');
      ServerList:= SQLServer.ListAvailableSQLServers;
      nServers:=ServerList.Count;
      for i := 1 to nservers do
          ListBox1.Items.Add(ServerList.Item(i));
      SQLServer:=NULL;
      serverList:=NULL;
    end;不过你试试,结果肯定失望,M$东西,都是骗人的
    NetServerEnum也是鬼知道好用不好用 
    左轻侯 (2000-12-27 23:2) 
    呵呵,一刀果然是忠心耿耿的Delphi fan 
    iamfly (2000-12-28 11:7) 
    昨天试了试下温柔一刀的,在我装了SQL的2000下是可以,但再进到我没装SQL的98下,就
    唉,算了,干脆不用这个了,要别人自己去输入SQL服务器名或IP算了,反正我的ADOCONNECTION
    是在TRY EXCEPT语句里面,检测到如果不能连通SQL服务器的会提示的。不过,我还是想知道
    以前的那几个方面:一、如果用zhuhuan的方法,IMPORT了SQL DMO LIBIRARY,SQLSERVER的
    APPLICATION会和程序中的APPLICATION对象起冲突?怎么解决??
    二、IKnow说的NETSERVERENUM有谁用过?能说说吗?
    三、一刀说的方法,如果没装SQL,能解决吗?(我在98下出错原因是这个CLSID没注册,不
    是要我手工去注册表中加吧)
    版主,能否再等几天,我看看有没有人答:)如果三天以上还是没人答,而我又不能来的话,
    你帮我结束吧,谢了^_^ 
    温柔一刀 (2000-12-28 12:59) 
    1.SQL-DMO是COM对象,没注册当然不行,如果一定要用,
    可以使用Installsheld之类注册相应的DLL2. 我上面的代码你应该看到了,SQLDMO也有一个Application对象,
    因此你use xxx_tlb.pas的时候,就把delphi forms.pas里面的application“挡住了”我说的方法与import tlb方法是等价的,因此你没必要使用tlb了。3.NETSERVERENUM是NetAPI函数,只有在NT下才有用,win98下别想了。 
    Iknow (2000-12-28 14:48) 
    我以前做的项目中对于netxxx的函数用delphi重写过一遍,
    不过是要在nt下运行的。95/98下的函数所在的dll和参数调用不太一样。
    85/98下是NetServerGetInfo, 在svrapi.dll中。另外,如果对thunk熟的话,也可以直接从windows 95的netapi.dll中使用NT中的这些函数.pas文件 我已经发给你了,算是便宜你了。 ^_* 
    iamfly (2000-12-29 10:8) 
    分分了,谢谢一刀兄,谢谢IKnow兄,EMAIL已收到,嗬嗬,我会慢慢去体会你的程序的,
    谢谢,谢谢,谢谢^_^ 
      

  2.   

    給你個單元, 它能夠獲取局域網內所有的SQL服務器,unit uEnumSQLServer;interfaceuses Windows, Classes, SysUtils;type
      NET_API_STATUS = DWORD;  PServerInfo100 = ^TServerInfo100;
      _SERVER_INFO_100 = record
        sv100_platform_id: DWORD;
        sv100_name: LPWSTR;
      end;
    {$EXTERNALSYM _SERVER_INFO_100}
      TServerInfo100 = _SERVER_INFO_100;
      SERVER_INFO_100 = _SERVER_INFO_100;
    {$EXTERNALSYM SERVER_INFO_100}const
      NERR_Success = 0;
      MAX_PREFERRED_LENGTH = DWORD(-1);
      SV_TYPE_SQLSERVER = $00000004;function NetApiBufferAllocate(ByteCount: DWORD; var Buffer: Pointer):
      NET_API_STATUS; stdcall; external 'netapi32.dll' name 'NetApiBufferAllocate';function NetServerEnum(ServerName: LPCWSTR; Level: DWORD; var BufPtr: Pointer;
      PrefMaxLen: DWORD; var EntriesRead: DWORD; var TotalEntries: DWORD;
      ServerType: DWORD; Domain: LPCWSTR; ResumeHandle: PDWORD): NET_API_STATUS;
    stdcall; external 'netapi32.dll' name 'NetServerEnum';function NetApiBufferFree(Buffer: Pointer): NET_API_STATUS; stdcall; external
    'netapi32.dll' name 'NetApiBufferFree';function GetSQLServerList(out AList: TStrings; pwcServerName: PWChar = nil;
      pwcDomain: PWChar = nil): Boolean;implementationfunction GetSQLServerList(out AList: TStrings; pwcServerName: PWChar = nil;
      pwcDomain: PWChar = nil): Boolean;
    var
      NetAPIStatus: DWORD;
      dwLevel: DWORD;
      pReturnSvrInfo: Pointer;
      dwPrefMaxLen: DWORD;
      dwEntriesRead: DWORD;
      dwTotalEntries: DWORD;
      dwServerType: DWORD;
      dwResumeHandle: PDWORD;
      pCurSvrInfo: PServerInfo100;
      i, j: Integer;
    begin
      Result := True;
      try
        if Trim(pwcServerName) = '' then
          pwcServerName := nil;    if Trim(pwcDomain) = '' then
          pwcDomain := nil;    dwLevel := 100;
        pReturnSvrInfo := nil;
        dwPrefMaxLen := MAX_PREFERRED_LENGTH;
        dwEntriesRead := 0;
        dwTotalEntries := 0;
        dwServerType := SV_TYPE_SQLSERVER;
        dwResumeHandle := nil;    NetApiBufferAllocate(SizeOf(pReturnSvrInfo), pReturnSvrInfo);
        try
          NetAPIStatus := NetServerEnum(pwcServerName, dwLevel, pReturnSvrInfo,
            dwPrefMaxLen, dwEntriesRead, dwTotalEntries, dwServerType, pwcDomain,
            dwResumeHandle);      if (NetAPIStatus = NERR_Success) and (pReturnSvrInfo <> nil) then
          begin
            pCurSvrInfo := pReturnSvrInfo;        i := 0;
            j := dwEntriesRead;
            while i < j do
            begin
              if pCurSvrInfo = nil then
                Break;          with AList do
                Add(pCurSvrInfo^.sv100_name);          Inc(i);
              Inc(pCurSvrInfo);
            end;
          end;
        finally
          if Assigned(pReturnSvrInfo) then
            NetApiBufferFree(pReturnSvrInfo);
        end;
      except
        Result := False;
      end;
    end;end.
      

  3.   

    我也知道可以得到sql服务器列表,但是如果局域网中有好几个sql服务,我总不能让客户每次都去选择吧?再说,他要是选错了还无法正常运行。所以我还是想能得到服务器的IP,然后直接连接服务器。高手赐教!
      

  4.   

    procedure TDBcon.FormCreate(Sender: TObject);
    var
       SQLServer:Variant;
       ServerList:Variant;
       i:integer;
    begin
    try
      SQLServer  :=  CreateOleObject('SQLDMO.Application');
      ServerList:=  SQLServer.ListAvailableSQLServers;
     if serverlist.count  <1  then
       begin  //如果服务器不存在,则退出系统
             showmessage('服务器不存在,请检测服务器是否已经开机或者服务是否打开了');
             Exit;
       End;
       for  i:=1  to  serverlist.count  do
         cbbserver.Items.Add(serverlist.item(i));
    finally
      SQLServer:=null;
      ServerList:=null;
    end;
      
    end;
      

  5.   

    楼主你说的可就不正确了!你是没认真想而已!你应该使用ini文件去记录你的连接字符串!当你从ini文件获取到的信息连接不到那个服务器的时候,才让客户去选择网络里面的服务器!当连接正确了再写回到ini文件里面,这样就不用那么麻烦了啊!干活要多想!多学,多问,多搜索!
      

  6.   

    〉〉我也知道可以得到sql服务器列表,如果局域网中有好几个sql服务
    〉〉还是想能得到服务器的IP,然后直接连接服务器。拜托,逻辑思维稍微专业一点..既然列表了就肯定要选择的
      

  7.   


    >>>所以我还是想能得到服务器的IP哎, 真搞水懂你的需求!獲取服务器的IP需要知道服務器的電腦名稱, 那麼如何獲取服務器的電腦名稱呢??
    獲取電腦名稱後, 根據名稱再來獲取它的IP地址.
      

  8.   

    >>下面的代碼是獲取網內的所有計算機名. 
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>
    unit Unit2;
    interface
    procedure GetDomainList(TV: TTreeView);
    var
      a: Integer;
      ErrCode: Integer;
      NetRes: array[0..1023] of TNetResource;
      EnumHandle: THandle;
      EnumEntries: DWord;
      BufferSize: DWord;
      s: string;
      itm: TTreeNode;
    begin
    { Start here }
      try
        with NetRes[0] do
        begin
          dwScope := RESOURCE_GLOBALNET;
          dwType := RESOURCETYPE_ANY;
          dwDisplayType := RESOURCEDISPLAYTYPE_DOMAIN;
          dwUsage := RESOURCEUSAGE_CONTAINER;
          lpLocalName := nil;
          lpRemoteName := nil;
          lpComment := nil;
          lpProvider := nil;
        end;
    { get net root }
        ErrCode := WNetOpenEnum(
          RESOURCE_GLOBALNET
          RESOURCETYPE_ANY
          RESOURCEUSAGE_CONTAINER
          @NetRes[0]
          EnumHandle
          );    if ErrCode = NO_ERROR then
        begin
          EnumEntries := 1;
          BufferSize := SizeOf(NetRes);
          ErrCode := WNetEnumResource(
            EnumHandle
            EnumEntries
            @NetRes[0]
            BufferSize
            );
          WNetCloseEnum(EnumHandle);
          ErrCode := WNetOpenEnum(
            RESOURCE_GLOBALNET
            RESOURCETYPE_ANY
            RESOURCEUSAGE_CONTAINER
            @NetRes[0]
            EnumHandle
            );
          EnumEntries := 1024;
          BufferSize := SizeOf(NetRes);
          ErrCode := WNetEnumResource(
            EnumHandle
            EnumEntries
            @NetRes[0]
            BufferSize
            );      if ErrCode = No_Error then
            with TV do
            try
              a := 0;
              Items.BeginUpDate;
              Items.Clear;
              Itm := Items.Add(TV.Selected
                string(NetRes[0].lpProvider));
              Itm.ImageIndex := 0;
              Itm.SelectedIndex := 0;
    { get domains }
            unit NetBrwsr;
      

  9.   


    interfaceuses
      Windows
      Messages
      SysUtils
      Classes
      Graphics
      Controls
      Forms
      Dialogs;type
      TNetScope = (nsConnected
        nsGlobal
        nsRemembered
        nsContext);
      TNetResourceType = (nrAny
        nrDisk
        nrPrint);
      TNetDisplay = (ndDomain
        ndGeneric
        ndServer
        ndShare
        ndFile
        ndGroup
        ndNetwork
        ndRoot
        ndShareAdmin
        ndDirectory
        ndTree
        ndNDSContainer);
      TNetUsage = set of (nuConnectable
        nuContainer);
      TNetworkItems = class;
      TNetworkItem = class
      private
        FScope: TNetScope;
        FResourceType: TNetResourceType;
        FDisplay: TNetDisplay;
        FUsage: TNetUsage;
        FLocalName: string;
        FRemoteName: string;
        FComment: string;
        FProvider: string;
        FSubItems: TNetworkItems;
      public
        constructor Create;
        destructor Destroy; override;
        property Scope: TNetScope read FScope;
        property ResourceType: TNetResourceType read FResourceType;
        property Display: TNetDisplay read FDisplay;
        property Usage: TNetUsage read FUsage;
        property LocalName: string read FLocalName;
        property RemoteName: string read FRemoteName;
        property Comment: string read FComment;
        property Provider: string read FProvider;
        property SubItems: TNetworkItems read FSubItems;
      end;
      TNetworkItems = class
      private
        FList: TList;
        procedure SetItem(Index: Integer; Value: TNetworkItem);
        function GetItem(Index: Integer): TNetworkItem;
        function GetCount: Integer;
      public
        constructor Create;
        destructor Destroy; override;
        procedure Clear;
        procedure Add(Item: TNetworkItem);
        procedure Delete(Index: Integer);
        property Items[Index: Integer]: TNetworkItem read GetItem write
        SetItem; default;
        property Count: Integer read GetCount;
      end;
      TNetworkBrowser = class(TComponent)
      private
        FItems: TNetworkItems;
        FScope: TNetScope;
        FResourceType: TNetResourceType;
        FUsage: TNetUsage;
        FActive: Boolean;
        procedure Refresh;
        procedure SetActive(Value: Boolean);
        procedure SetScope(Value: TNetScope);
        procedure SetResourceType(Value: TNetResourceType);
        procedure SetUsage(Value: TNetUsage);
        procedure EnumerateNet(NetItems: TNetworkItems; lpnr: PNetResource);
      protected
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
        procedure Open;
        procedure Close;
        property Items: TNetworkItems read FItems;
      published
        property Scope: TNetScope read FScope write SetScope default nsGlobal;
        property ResourceType: TNetResourceType read FResourceType
        write SetResourceType default nrAny;
        property Usage: TNetUsage read FUsage write SetUsage default [];
        property Active: Boolean read FActive write SetActive default False;
      end;implementationtype
      PNetResourceArray = ^TNetResourceArray;
      TNetResourceArray = array[0..0] of TNetResource;{ TNetworkItem }constructor TNetworkItem.Create;
    begin
      inherited;
      FSubItems := TNetworkItems.Create;
    end;destructor TNetworkItem.Destroy;
    begin
      if FSubItems <> nil then
        FSubItems.Free;
      inherited;
    end;{ TNetworkItems }constructor TNetworkItems.Create;
    begin
      inherited;
      FList := TList.Create;
    end;destructor TNetworkItems.Destroy;
    begin
      Clear;
      if FList <> nil then
        FList.Free;
      inherited;
    end;
    procedure TNetworkItems.SetItem(Index: Integer; Value: TNetworkItem);
    begin
      if (FList.Items[Index] <> nil) and (FList.Items[Index] <> Value) then
        TNetworkItem(FList.Items[Index]).Free;
      FList.Items[Index] := Value;
    end;
    function TNetworkItems.GetItem(Index: Integer): TNetworkItem;
    begin
      Result := TNetworkItem(FList.Items[Index]);
    end;
    procedure TNetworkItems.Clear;
    begin
      while Count > 0 do
        Delete(0);
    end;procedure TNetworkItems.Add(Item: TNetworkItem);
    begin
      FList.Add(Item);
    end;procedure TNetworkItems.Delete(Index: Integer);
    begin
      if FList.Items[Index] <> nil then
        TNetworkItem(FList.Items[Index]).Free;
      FList.Delete(Index);
    end;
      

  10.   

    http://jonnysun.mblogger.cn/posts/23756.aspx
    http://jonnysun.mblogger.cn/posts/23757.aspx
      

  11.   

    非常感谢各位热心指导。其实用INI或注册表是可以解决的。揭帖!