![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Список серверов SQL в сети [D7, MSSQL]
Orc © (2005-01-10 11:52:00)Вопрос таков: как получить список всех доступных серверов SQL в локалке? И возможно ли это реализовать без использования OLE-сервера SQLDMO? Заранее благодарен за множество ценных ответов ;)
sniknik (2005-01-10 14:20:00) [1]Misha Uskov © (10.01.05 13:56) [8]
авторство не совсем мое, скорее "по мотивам", по сети гуляет куча аналогичных таких модулей, только вот именно эта реализация моя, узнаваемо,
т.к. делалось для того чтобы срабатывало на компе с отсутствующим ODBC (не думаю чтобы у когото это повторилось (маразм был полный)... т.е. ODBC обычно присутствует на 100% компов), именно поэтому динамическая линковка dll в других будет стистическая (оно быстрее, но не даст запустится проге при отсутствии). и именно поэтому у меня в проге для определения серверов смешано 3 метода (до первого сработавшего), все изза любителей которые начитавшись хакера удаляют "лишние" части из виндов, а после считают себя крытыми админами. (нам было проше исправить прогу чем "бодатся" с таким, и было это гдето 2 года назад (в прошлой ветке я не не сразу модуль даже нашол ;о))))
Orc (2005-01-10 14:03:00) [2]2BiN:
А как же! :)
2sniknik: Ура! Заработало! Спасибо!
BiN (2005-01-10 13:59:00) [3]Orc © (10.01.05 13:56) [9]
Юзал NetServerEnum, параметр servertype установил SV_TYPE_SQLSERVER - не помогает. Список возвращает, канешна, но не полный.
Разумеется, результаты функции ты обрабатывал(?)
Misha Uskov (2005-01-10 13:56:00) [4][6] sniknik © (10.01.05 13:47)
Извини. я не привел авторство по той причине, что не знал автора. Ввести в заблуждение, что это мой код - не хотел. Когда я искал ответ на тот же вопрос, что и в сабж, наткнулся на твое решение и просто вставил функцию в проект без ссылок, откуда я ее взял :-(
Orc (2005-01-10 13:56:00) [5]2BiN:
Юзал NetServerEnum, параметр servertype установил SV_TYPE_SQLSERVER - не помогает. Список возвращает, канешна, но не полный.
BiN (2005-01-10 13:54:00) [6]Всё же, проще всего - использовать NetServerEnum (особо см. параметр servertype )
sniknik (2005-01-10 13:47:00) [7]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.
Orc (2005-01-10 13:42:00) [8]2Misha Uskov:
Чтобы пользоваться SQLHDBC (ну и остальным) что-то подключать в uses надо? Или ActiveX какой инсталлить?
Nikolay M. (2005-01-10 13:34:00) [9]
> ShotGuN © (10.01.05 12:59) [3]
> возможно ли это реализовать безиспользования OLE-сервера
> SQLDMO
ShotGuN (2005-01-10 12:59:00) [10]
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;
Misha Uskov (2005-01-10 12:30:00) [11]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;
Nikolay M. (2005-01-10 12:27:00) [12]И почему каждый уверен, что у него первого такой вопрос возник???
http://www.sql.ru/forum/actualtopics.aspx?search=ListAvailableSQLServers&submit=%CD%E0%E9%F2%E8&bid=1