Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];

Вниз

Список серверов SQL в сети   Найти похожие ветки 

 
Orc ©   (2005-01-10 11:52) [0]

Вопрос таков: как получить список всех доступных серверов SQL в локалке? И возможно ли это реализовать без использования OLE-сервера SQLDMO? Заранее благодарен за множество ценных ответов ;)


 
Nikolay M. ©   (2005-01-10 12:27) [1]

И почему каждый уверен, что у него первого такой вопрос возник???
http://www.sql.ru/forum/actualtopics.aspx?search=ListAvailableSQLServers&submit=%CD%E0%E9%F2%E8&bid=1


 
Misha Uskov ©   (2005-01-10 12:30) [2]

function GetSQLServersODBC(List: TStrings): boolean;
const
 BRWS_LEN = 1024;
var
 Hdbc: SQLHDBC;
 Henv: SQLHENV;
 ResArr: array of char;
 OutLen: SQLSMALLINT;
 sTrt, sEnd: integer;
begin
 result:= false;
 List.Clear;

 if DllHandle = 0 then
 begin
   DllHandle:= LoadLibrary(PChar("odbc32.dll"));
   if DllHandle < 32 then Exit;

   SQLAllocHandle:= GetProcAddress(DllHandle, "SQLAllocHandle");
   if @SQLAllocHandle = nil then begin DllHandle:= 0; Exit; end;
   SQLSetEnvAttr:= GetProcAddress(DllHandle, "SQLSetEnvAttr");
   if @SQLSetEnvAttr = nil then begin DllHandle:= 0; Exit; end;
   SQLBrowseConnect:= GetProcAddress(DllHandle, "SQLBrowseConnect");
   if @SQLBrowseConnect = nil then begin DllHandle:= 0; Exit; end;
   SQLFreeHandle:= GetProcAddress(DllHandle, "SQLFreeHandle");
   if @SQLFreeHandle = nil then begin DllHandle:= 0; Exit; end;
 end;

 Hdbc:= nil;
 Henv:= nil;
 if not (SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, Henv) in [SQL_SUCCESS, SQL_SUCCESS_WITH_INFO]) then Exit;
 try
  if not (SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3, 0) in [SQL_SUCCESS,SQL_SUCCESS_WITH_INFO]) then Exit;
  if not (SQLAllocHandle(SQL_HANDLE_DBC, henv, hdbc) in [SQL_SUCCESS,SQL_SUCCESS_WITH_INFO]) then Exit;
  try
    SetLength(ResArr, BRWS_LEN);
   if SQLBrowseConnect(hdbc, "DRIVER={SQL Server};", SQL_NTS, Pointer(ResArr), BRWS_LEN, OutLen) <> SQL_NEED_DATA then Exit;
    if BRWS_LEN < OutLen then begin
      SetLength(ResArr, OutLen+1);
      if SQLBrowseConnect(hdbc, "DRIVER={SQL Server};", SQL_NTS, Pointer(ResArr), OutLen, OutLen) <> SQL_NEED_DATA then Exit;
    end;

    sTrt:= Pos("{", PChar(ResArr));
    sEnd:= Pos("}", PChar(ResArr));
    List.Delimiter:= ",";
    List.DelimitedText:= Copy(PChar(ResArr), sTrt+1, sEnd-sTrt-1);

    SetLength(ResArr, 0);
  result:= true;
  finally
    SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
  end;
finally
  SQLFreeHandle(SQL_HANDLE_ENV, henv);
end;
end;


 
ShotGuN ©   (2005-01-10 12:59) [3]

Var
 V : Variant;
 I : Integer;
begin
 v:=CreateOleObject("SQLDMO.Application");
 ComboBox1.Items.Clear ;
 if v.ListAvailableSQLServers.Count > 0 then
   For i:=1 to v.ListAvailableSQLServers.Count do
    ComboBox1.Items.Add(v.ListAvailableSQLServers.Item(i));
end;


 
Nikolay M. ©   (2005-01-10 13:34) [4]


> ShotGuN ©   (10.01.05 12:59) [3]



> возможно ли это реализовать без использования OLE-сервера
> SQLDMO


 
Orc ©   (2005-01-10 13:42) [5]

2Misha Uskov:

Чтобы пользоваться SQLHDBC (ну и остальным) что-то подключать в uses надо? Или ActiveX какой инсталлить?


 
sniknik ©   (2005-01-10 13:47) [6]

Misha Uskov ©   (10.01.05 12:30) [2]
приводиш так приводи полностью с декларациями (а то пожалею что давал когдато ;о))

кстати тема была, и нет давно, там при водил как минимум 2 варианта (вот этот с ODBC и еще самостоятельное сканирование сети) оба без OLE
поищи (возможно в дайджестах уже)

unit Odbc32;

interface

uses
Windows, Classes;

function GetSQLServersODBC(List: TStrings): boolean;

implementation

type
SQLRETURN = ShortInt;
SQLHANDLE = Pointer;
SQLHANDLEPTR = ^Pointer;
SQLHDBC = SQLHANDLE;
SQLHENV = SQLHANDLE;
SQLHSTMT = SQLHANDLE;
SQLCHAR = PChar;
SQLSMALLINT = SmallInt;
SQLSMALLINTPTR = ^ShortInt;
SQLINTEGER = Integer;
SQLPOINTER = Pointer;

const
SQL_HANDLE_ENV = 1;
SQL_NULL_HANDLE = nil;
SQL_SUCCESS = 0;
SQL_SUCCESS_WITH_INFO = 1;
SQL_HANDLE_DBC = 2;
SQL_NTS = -3;
SQL_NEED_DATA = 99;
SQL_ATTR_ODBC_VERSION = 200;
 
SQL_OV_ODBC3: SQLPOINTER = pointer(3);

var
 DllHandle: THandle;
 SQLAllocHandle: function(HandleType: SQLSMALLINT; InputHandle: SQLHANDLE; var OutputHandle: SQLHANDLE): SQLRETURN; stdcall;
 SQLSetEnvAttr: function(EnvironmentHandle: SQLHENV; Attribute: SQLINTEGER; ValuePtr: SQLPOINTER;StringLength: SQLINTEGER): SQLRETURN; stdcall;
 SQLBrowseConnect: function(ConnectionHandle: SQLHDBC; InConnectionString: SQLCHAR;StringLength1: SQLSMALLINT; OutConnectionString: SQLCHAR; BufferLength: SQLSMALLINT;var StringLength2: SQLSMALLINT): SQLRETURN; stdcall;
 SQLFreeHandle: function(HandleType: SQLSMALLINT; Handle: SQLHANDLE): SQLRETURN; stdcall;

function GetSQLServersODBC(List: TStrings): boolean;
const
BRWS_LEN = 1024;
var
 Hdbc: SQLHDBC;
Henv: SQLHENV;
 ResArr: array of char;
OutLen: SQLSMALLINT;
 sTrt, sEnd: integer;
begin
result:= false;
 List.Clear;

 if DllHandle = 0 then begin
   DllHandle:= LoadLibrary(PChar("odbc32.dll"));
   if DllHandle < 32 then Exit;

   SQLAllocHandle:= GetProcAddress(DllHandle, "SQLAllocHandle");
   if @SQLAllocHandle = nil then begin DllHandle:= 0; Exit; end;
   SQLSetEnvAttr:= GetProcAddress(DllHandle, "SQLSetEnvAttr");
   if @SQLSetEnvAttr = nil then begin DllHandle:= 0; Exit; end;
   SQLBrowseConnect:= GetProcAddress(DllHandle, "SQLBrowseConnect");
   if @SQLBrowseConnect = nil then begin DllHandle:= 0; Exit; end;
   SQLFreeHandle:= GetProcAddress(DllHandle, "SQLFreeHandle");
   if @SQLFreeHandle = nil then begin DllHandle:= 0; Exit; end;
 end;

Hdbc:= nil;
Henv:= nil;
if not (SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, Henv) in [SQL_SUCCESS, SQL_SUCCESS_WITH_INFO]) then Exit;
 try
 if not (SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3, 0) in [SQL_SUCCESS,SQL_SUCCESS_WITH_INFO]) then Exit;
   if not (SQLAllocHandle(SQL_HANDLE_DBC, henv, hdbc) in [SQL_SUCCESS,SQL_SUCCESS_WITH_INFO]) then Exit;
   try
     SetLength(ResArr, BRWS_LEN);
    if SQLBrowseConnect(hdbc, "DRIVER={SQL Server};", SQL_NTS, Pointer(ResArr), BRWS_LEN, OutLen) <> SQL_NEED_DATA then Exit;
     if BRWS_LEN < OutLen then begin
       SetLength(ResArr, OutLen+1);
       if SQLBrowseConnect(hdbc, "DRIVER={SQL Server};", SQL_NTS, Pointer(ResArr), OutLen, OutLen) <> SQL_NEED_DATA then Exit;
     end;

     sTrt:= Pos("{", PChar(ResArr));
     sEnd:= Pos("}", PChar(ResArr));
     List.Delimiter:= ",";
     List.DelimitedText:= Copy(PChar(ResArr), sTrt+1, sEnd-sTrt-1);

     SetLength(ResArr, 0);
   result:= true;
   finally
     SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
   end;
 finally
   SQLFreeHandle(SQL_HANDLE_ENV, henv);
 end;
end;

end.


 
BiN ©   (2005-01-10 13:54) [7]

Всё же, проще всего - использовать NetServerEnum (особо см. параметр servertype )


 
Misha Uskov ©   (2005-01-10 13:56) [8]

[6] sniknik ©   (10.01.05 13:47)
Извини. я не привел авторство по той причине, что не знал автора. Ввести в заблуждение, что это мой код - не хотел. Когда я искал ответ на тот же вопрос, что и в сабж, наткнулся на твое решение и просто вставил функцию в проект без ссылок, откуда я ее взял :-(


 
Orc ©   (2005-01-10 13:56) [9]

2BiN:

Юзал NetServerEnum, параметр servertype установил SV_TYPE_SQLSERVER - не помогает. Список возвращает, канешна, но не полный.


 
BiN ©   (2005-01-10 13:59) [10]

Orc ©   (10.01.05 13:56) [9]
Юзал NetServerEnum, параметр servertype установил SV_TYPE_SQLSERVER - не помогает. Список возвращает, канешна, но не полный.


Разумеется, результаты функции ты обрабатывал(?)


 
Orc ©   (2005-01-10 14:03) [11]

2BiN:

А как же! :)

2sniknik: Ура! Заработало! Спасибо!


 
sniknik ©   (2005-01-10 14:20) [12]

Misha Uskov ©   (10.01.05 13:56) [8]
авторство не совсем мое, скорее "по мотивам", по сети гуляет куча аналогичных таких модулей, только вот именно эта реализация моя, узнаваемо,
т.к. делалось для того чтобы срабатывало на компе с отсутствующим ODBC (не думаю чтобы у когото это повторилось (маразм был полный)... т.е. ODBC обычно присутствует на 100% компов), именно поэтому динамическая линковка dll в других будет стистическая (оно быстрее, но не даст запустится проге при отсутствии). и именно поэтому у меня в проге для определения серверов смешано 3 метода (до первого сработавшего), все изза любителей которые начитавшись хакера удаляют "лишние" части из виндов, а после считают себя крытыми админами. (нам было проше исправить прогу чем "бодатся" с таким, и было это гдето 2 года назад (в прошлой ветке я не не сразу модуль даже нашол ;о))))



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.034 c
1-1106220683
salexn
2005-01-20 14:31
2005.02.06
RichEdit и поиск текста


1-1106402346
kyn66
2005-01-22 16:59
2005.02.06
как найти дублирующиеся значения полей в таблице


4-1103122941
Александер
2004-12-15 18:02
2005.02.06
Общение с окном чужого приложения


4-1102672210
Steepe Wolf
2004-12-10 12:50
2005.02.06
Перехват данных с COM - порта


1-1106408303
kyn66
2005-01-22 18:38
2005.02.06
Как установить EasyTable 6.03 D6





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский