使用delphi枚举本地网络上的Microsoft SQL数据库服务器

时间:2012-05-15 22:31:40

标签: sql-server delphi

如果我使用C#,我可以使用.net framework SqlDataSourceEnumerator来发现并向用户显示网络上的SQL Server实例列表。

我怎么能在Delphi中做到这一点?

3 个答案:

答案 0 :(得分:11)

您可以使用NetServerEnum函数,按servertype参数中的SV_TYPE_SQLSERVER值进行过滤,另一个选项是使用SQLOLEDB Enumerator ADO对象。

答案 1 :(得分:4)

我使用此代码:

uses ActiveX,
     ComObj,
     OleDB,
     DB,
     ADOInt,
     ADODB;

procedure ListAvailableSQLServers(Names: TStringList);
var
  RSCon: ADORecordsetConstruction;
  Rowset: IRowset;
  SourcesRowset: ISourcesRowset;
  SourcesRecordset: _Recordset;
  SourcesName, SourcesType: TField;

function PtCreateADOObject(const ClassID: TGUID): IUnknown;
var
  Status: HResult;
  FPUControlWord: Word;
begin
  asm
    FNSTCW FPUControlWord
  end;
  Status := CoCreateInstance(
              CLASS_Recordset,
              nil,
              CLSCTX_INPROC_SERVER or
              CLSCTX_LOCAL_SERVER,
              IUnknown,
              Result);
  asm
    FNCLEX
    FLDCW FPUControlWord
  end;
  OleCheck(Status);
end;

begin
  SourcesRecordset :=
       PtCreateADOObject(CLASS_Recordset)
       as _Recordset;
  RSCon :=
       SourcesRecordset
       as ADORecordsetConstruction;
   SourcesRowset :=
       CreateComObject(ProgIDToClassID('SQLOLEDB Enumerator'))
       as ISourcesRowset;
   OleCheck(SourcesRowset.GetSourcesRowset(
            nil,
            IRowset, 0,
            nil,
            IUnknown(Rowset)));
   RSCon.Rowset := RowSet;
   with TADODataSet.Create(nil) do
   try
     Recordset := SourcesRecordset;
     SourcesName := FieldByName('SOURCES_NAME');
     SourcesType := FieldByName('SOURCES_TYPE');
     Names.BeginUpdate;
     Names.Clear;
     try
        while not EOF do
        begin
          if (SourcesType.AsInteger = DBSOURCETYPE_DATASOURCE) and
             (SourcesName.AsString <> '') then
            Names.Add(SourcesName.AsString);
          Next;
        end;
     finally
        Names.EndUpdate;
     end;
  finally
     Free;
  end;
end;




procedure GetServer();
var
  oItems: TStringList;
begin
  oItems:= TStringList.Create;
  try
    ListAvailableSQLServers(oItems);
    // To something with oItems
    ShowMessage(oItems.Text);
  finally
    oItems.Free;
  end;
end;

答案 2 :(得分:4)

要枚举所有可用的Microsoft SQL Server,您可以遵循以下优秀教程:

  

Enumerating available SQL Servers. Retrieving databases on a SQL Server

包含在Zarko的教程中,有download the full source code (direct download)的链接,可以快速测试并检查是否符合您的需求。

编辑 Zarko Gajic的主要例程是:

procedure ListAvailableSQLServers(Names : TStrings);
var
  RSCon: ADORecordsetConstruction;
  Rowset: IRowset;
  SourcesRowset: ISourcesRowset;
  SourcesRecordset: _Recordset;
  SourcesName, SourcesType: TField;

    function PtCreateADOObject(const ClassID: TGUID): IUnknown;
    var
      Status: HResult;
      FPUControlWord: Word;
    begin
      asm
        FNSTCW FPUControlWord
      end;
      Status := CoCreateInstance(
                  CLASS_Recordset,
                  nil,
                  CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER,
                  IUnknown,
                  Result);
      asm
        FNCLEX
        FLDCW FPUControlWord
      end;
      OleCheck(Status);
    end;
begin
  SourcesRecordset := PtCreateADOObject(CLASS_Recordset) as _Recordset;
  RSCon := SourcesRecordset as ADORecordsetConstruction;
  SourcesRowset := CreateComObject(ProgIDToClassID('SQLOLEDB Enumerator')) as ISourcesRowset;
  OleCheck(SourcesRowset.GetSourcesRowset(nil, IRowset, 0, nil, IUnknown(Rowset)));
  RSCon.Rowset := RowSet;
  with TADODataSet.Create(nil) do
  try
    Recordset := SourcesRecordset;
    SourcesName := FieldByName('SOURCES_NAME'); { do not localize }
    SourcesType := FieldByName('SOURCES_TYPE'); { do not localize }
    Names.BeginUpdate;
    try
      while not EOF do
      begin
        if (SourcesType.AsInteger = DBSOURCETYPE_DATASOURCE) and (SourcesName.AsString <> '') then
          Names.Add(SourcesName.AsString);
        Next;
      end;
    finally
      Names.EndUpdate;
    end;
  finally
    Free;
  end;
end;

我不知道如果没有 lamering Zako的解释,我可以添加什么。

相关问题