Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enumerate Microsoft SQL database servers on the local network, using delphi

If I was using C# I could use the .net framework's SqlDataSourceEnumerator to discover and show a user a list of SQL Server instances on the network.

How can I do that in Delphi?

like image 776
Warren P Avatar asked May 15 '12 22:05

Warren P


2 Answers

You can use the NetServerEnum function , filtering by the SV_TYPE_SQLSERVER value in the servertype param, another option is use the SQLOLEDB Enumerator ADO object.

like image 131
RRUZ Avatar answered Sep 29 '22 21:09

RRUZ


To enumerate all available Microsoft SQL Servers, you can follow this excellent tutorial:

Enumerating available SQL Servers. Retrieving databases on a SQL Server

Included in Zarko's tutorial, there's a link to download the full source code (direct download) which can be useful to quickly test it and check if it fits your needs.

Edit Zarko Gajic's main routine is:

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;

I don't know what I can add without lamering what Zarko's explained.

like image 32
Whiler Avatar answered Sep 29 '22 19:09

Whiler