-
Подскажите как получить список серверов и баз данных на сервере? в качестве примера - настройка ADOConnection, эта информация наверное берется из реестра (если да то из какого раздела).
-
> эта информация наверное берется из реестра
нет.
> Подскажите как получить список серверов и баз данных на > сервере?
Если тебе известен сервер и ты имеешь к нему такой доступ, что можешь прочитать master, тогда select name from sysdatabases
А вот с сервером - сложнее. По-идее - опрос 1433 порта на компах в сети (этот порт у MSSQL по-умолчанию). Но неоднократно натыкался на такое: есть сеть. Как-то настроены права пользователей и т.п. (я в этих делах не силен). По DNS-имени сервера (Имя_Компьютера\Имя_Инстанса) соединение не устанавливается. А вот по IP-сервера (IP_компьютера\Имя_Инстанса) - запросто.
Так что я бы на твоём месте сделал бы так: Имя сервера, логин и пароль пользователь вводит ручками, а вот конкретную базу уже можно выбрать так, как я писал выше. Хотя я вообще на это дело не заморачиваюсь - всё ручками.
-
Спасибо большое! я теперь хотя бы понимаю в каком направлении копать. Насчет все руками - согласен (простой оператор не должен заморачиваться с настройкой программы).
-
> Ega23 (09.10.2008 18:48:01) [1]
Вообще то идея неправильная, порт 1344 - SQL Browser, но особо расчитывать на это не стоит. Кроме того есть ВинАПИ, функция NetServerEnum
-
uses WinSock
type
RSQLServerVersion = record
VersNum: string;
ModNum: string;
end;
PMSSQLServerDef = ^RMSSQLServerDef;
RMSSQLServerDef = record
ServerName: string; InstanceName: string; IsClustered: boolean; Version: RSQLServerVersion; Port: integer; Path: string; end;
...
procedure SQLServ_GetServersList(SQLServerList: TList);
var
hSocket: TSocket;
WSAData: TWSAData;
Buf: array[0..65535] of byte;
i, tRes, tLenSA, tLenBufRecv: integer;
tLenBufIOCTL: u_long;
S: AnsiString;
saSQLSend, saSQLRecv: sockaddr_in;
Data: byte;
ServDef: PMSSQLServerDef;
ls: TStrings;
const
fBroadcast: boolean = True;
begin
for i := 0 to SQLServerList.Count-1 do
Dispose(PMSSQLServerDef(SQLServerList[i]));
SQLServerList.Clear;
Data := $02;
WSAStartup(MakeWord(2,2), WSAData); hSocket := Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (hSocket = INVALID_SOCKET) then exit;
tRes := setsockopt(hSocket, SOL_SOCKET, SO_BROADCAST, @fBroadcast, sizeof(BOOL));
if (tRes = SOCKET_ERROR) then begin closeSocket(hSocket); exit; end;
saSQLSend.sin_family := AF_INET;
saSQLSend.sin_port := htons(1434);
saSQLSend.sin_addr.s_addr := htonl(INADDR_BROADCAST);
tRes := sendto(hSocket, Data, 1, 0, saSQLSend, sizeof(SOCKADDR_IN));
if (tRes = SOCKET_ERROR) then begin closeSocket(hSocket); exit; end;
Sleep(100); tRes := ioctlSocket(hSocket,FIONREAD,tLenBufIOCTL); if (tRes = SOCKET_ERROR) then begin closeSocket(hSocket); exit; end;
if (tLenBufIOCTL>0) then begin
tLenSA := sizeof(SOCKADDR_IN);
saSQLRecv := saSQLSend;
while tLenBufIOCTL>0 do begin
tLenBufRecv := recvfrom(hSocket, Buf, 65535, 0, saSQLRecv, tLenSA);
tLenBufIOCTL := tLenBufIOCTL-tLenBufRecv;
if(tLenBufRecv=SOCKET_ERROR) then begin closeSocket(hSocket); exit; end;
s := ''; for i := 3 to tLenBufRecv-3 do s := s+Chr(Buf[i]);
ls := TStringList.Create;
while Length(s)>0 do
begin
i := Pos(';',s);
if i>0 then
begin ls.Add(Trim(Copy(s,1,i-1))); Delete(s,1,i); end
else
begin ls.Add(s); s := ''; end;
end;
if ls.IndexOf('ServerName')>-1 then
begin
ServDef := NEW(PMSSQLServerDef);
if ls.Count>(ls.IndexOf('ServerName')+1) then
ServDef.ServerName := ls[ls.IndexOf('ServerName')+1];
if (ls.IndexOf('InstanceName')>-1) and
(ls.Count>(ls.IndexOf('InstanceName')+1)) then
ServDef.InstanceName := ls[ls.IndexOf('InstanceName')+1];
if (ls.IndexOf('IsClastered')>-1) and
(ls.Count>(ls.IndexOf('IsClastered')+1)) then
ServDef.IsClustered := not (ls[ls.IndexOf('IsClastered')+1]='No');
if (ls.IndexOf('Version')>-1) and
(ls.Count>(ls.IndexOf('Version')+1)) then
begin
S := ls[ls.IndexOf('Version')+1];
i := Pos('.',S);
if i>0 then
begin
ServDef.Version.VersNum := Copy(S,1,i-1);
ServDef.Version.ModNum := Copy(S,i+1,Length(S)-i);
end
else
begin
ServDef.Version.VersNum := S;
ServDef.Version.ModNum := '';
end;
end;
if (ls.IndexOf('tcp')>-1) and
(ls.Count>(ls.IndexOf('tcp')+1)) then
ServDef.Port := StrToIntDef(ls[ls.IndexOf('tcp')+1],0);
if (ls.IndexOf('np')>-1) and
(ls.Count>(ls.IndexOf('np')+1)) then
ServDef.Path := ls[ls.IndexOf('np')+1];
SQLServerList.Add(ServDef);
end;
end;
end;
closeSocket(hSocket);
WSACleanup;
end;
-
> Вообще то идея неправильная, порт 1344 - SQL Browser,
1433 Специально сейчас залез, посмотрел настройку TCP/IP По-умолчанию - 1433, также предлагается его поменять и ещё какая-то опция Hide Server.
> Кроме того есть ВинАПИ, функция NetServerEnum
Возможно. Но она один фиг как-то должна работать. А как, если не порт сканить?
-
Ну я, собственно, так и предполагал.
-
> Ega23 (09.10.2008 20:32:05) [5]
Это функции LanMan им порты и TCP не нужны.
-
> Ega23 (09.10.2008 20:33:06) [6]
А это запрос к SQL Browser, не гарантируется работоспособность, по множеству причин.
-
Anatoly Podgoretsky © (09.10.08 20:51) [7]
Это функции LanMan им порты и TCP не нужны.
:)
Ага. Значить при "Отключить NetBIOS через TCP/IP" - работать не будет?
-
> isasa (13.10.2008 15:35:09) [9]
Ничего не значит, есть и через DS, сейчас фиг поймешь, что делать, что бы отключить "NetBIOS" и что в реальности подразумевается под этим "Отключить NetBIOS через TCP/IP" - всяко не то, что было раньше в НТ4/w9x
-
Вот я и говорю "?". Но попробовать не могу, нет D.
|