SQL - zapytanie o adres IP serwera

97

Czy w SQL Server 2005 jest zapytanie, za pomocą którego mogę uzyskać adres IP lub nazwę serwera?

Seibar
źródło
Podczas łączenia się z SQL przy użyciu nasłuchiwania AG, wygląda na to, że CONNECTIONPROPERTY („local_net_address”) zwraca adres IP nasłuchiwania zamiast adresu IP serwera.
brian beuning

Odpowiedzi:

147
SELECT  
   CONNECTIONPROPERTY('net_transport') AS net_transport,
   CONNECTIONPROPERTY('protocol_type') AS protocol_type,
   CONNECTIONPROPERTY('auth_scheme') AS auth_scheme,
   CONNECTIONPROPERTY('local_net_address') AS local_net_address,
   CONNECTIONPROPERTY('local_tcp_port') AS local_tcp_port,
   CONNECTIONPROPERTY('client_net_address') AS client_net_address 

Kod tutaj da ci adres IP;

Będzie to działać dla zdalnego żądania klienta do SQL 2008 i nowszych.

Jeśli masz dozwolone połączenia z pamięcią współdzieloną, to uruchomi się powyżej na samym serwerze

  • „Pamięć współdzielona” jako wartość „net_transport” i
  • NULL dla „local_net_address” i
  • <local machine>” pojawi się w „client_net_address”.

„client_net_address” to adres komputera, z którego pochodzi żądanie, podczas gdy „local_net_address” oznaczałby serwer SQL (czyli NULL w połączeniach z pamięcią współdzieloną), a adres, który dałbyś komuś, kto nie może używać NetBios serwera name lub FQDN z jakiegoś powodu.

Odradzam używanie tej odpowiedzi . Włączenie powłoki to bardzo zły pomysł na produkcyjnym serwerze SQL.

Jeff Muzzy
źródło
3
Dobra odpowiedź, z wyjątkiem tego, że otrzymuję ujemny numer portu (-15736) dla portu, który powinien wynosić 49800. Czy więc jeśli jest ujemny, można bezpiecznie dodać 65536?
crokusek
Jeśli ktoś chce zalogować się zdalnie do serwera SQL mojego komputera, jakie IP mu dać? local_net_address czy client_net_address?
david Blaine
@rene - rozważał to, ale pierwotna odpowiedź sama w sobie jest poprawna (dla SQL2008 + i połączeń zdalnych), więc po prostu pomyślałem, aby wyjaśnić, co oznaczają parametry ConnectionProperty. Oczywiście odpowiedź Chrisa Leonarda (dm_exec_connections) również jest poprawna, z tych samych powodów. Jeśli uważasz, że mój dodatek jest lepszy jako oddzielna odpowiedź, niż nie krępuj się, aby tak było :) Przez jakiś czas nie odpowiadałem na pytania, więc polityka i zasady tutaj mogły ulec zmianie (przeczytam je teraz ...)
Martin S. Stoller
Powód dodania zgodnie z „ stackoverflow.com/help/editing ”: wyjaśnienie znaczenia posta (bez zmiany tego znaczenia).
Martin S. Stoller
1
@ MartinS.Stoller Edytowałem Twój dodatek, aby był bardziej czytelny. Sprawdź, czy niczego nie przegapiłem.
odnowienie
33

Możesz uzyskać [nazwa hosta] \ [nazwa instancji] przez:

SELECT @@SERVERNAME;

Aby uzyskać tylko nazwę hosta, jeśli masz format nazwa hosta \ nazwa instancji:

SELECT LEFT(ltrim(rtrim(@@ServerName)), Charindex('\', ltrim(rtrim(@@ServerName))) -1)

Alternatywnie, jak wskazał @GilM:

SELECT SERVERPROPERTY('MachineName')

Możesz uzyskać rzeczywisty adres IP za pomocą tego:

create Procedure sp_get_ip_address (@ip varchar(40) out)
as
begin
Declare @ipLine varchar(200)
Declare @pos int
set nocount on
          set @ip = NULL
          Create table #temp (ipLine varchar(200))
          Insert #temp exec master..xp_cmdshell 'ipconfig'
          select @ipLine = ipLine
          from #temp
          where upper (ipLine) like '%IP ADDRESS%'
          if (isnull (@ipLine,'***') != '***')
          begin 
                set @pos = CharIndex (':',@ipLine,1);
                set @ip = rtrim(ltrim(substring (@ipLine , 
               @pos + 1 ,
                len (@ipLine) - @pos)))
           end 
drop table #temp
set nocount off
end 
go

declare @ip varchar(40)
exec sp_get_ip_address @ip out
print @ip

Źródło skryptu SQL .

Brian R. Bondy
źródło
20

Serwer może mieć wiele adresów IP, na których nasłuchuje. Jeśli twoje połączenie ma przyznane uprawnienie serwera VIEW SERVER STATE, możesz uruchomić tę kwerendę, aby uzyskać adres, który podłączyłeś do SQL Server:

SELECT dec.local_net_address
FROM sys.dm_exec_connections AS dec
WHERE dec.session_id = @@SPID;

To rozwiązanie nie wymaga wysyłania do systemu operacyjnego za pośrednictwem xp_cmdshell, co jest techniką, którą należy wyłączyć (lub przynajmniej ściśle zabezpieczyć) na serwerze produkcyjnym. Może wymagać nadania VIEW SERVER STATE do odpowiedniego loginu, ale jest to znacznie mniejsze zagrożenie bezpieczeństwa niż uruchomienie xp_cmdshell.

Preferowana jest technika wymieniona przez GilM dla nazwy serwera:

SELECT SERVERPROPERTY(N'MachineName');
skye --- kapitanie
źródło
Dzięki za tę odpowiedź ... Uważam, że jest to prawdziwy sposób określenia adresu IP serwera, jeśli chcesz go zweryfikować po stronie połączenia klienta, szczególnie jeśli połączenie klienta zostało nawiązane za pomocą ciągu połączenia, który zawierał alias SQL lub nazwany wystąpienie jako źródło danych.
Rodolfo G.
11

Większość rozwiązań do uzyskiwania adresu IP za pośrednictwem t-sql należy do tych dwóch obozów:

  1. Uruchom ipconfig.exeprzez xp_cmdshelli przeanalizuj dane wyjściowe

  2. Zapytanie DMV sys.dm_exec_connections

Nie jestem fanem opcji nr 1. Włączenie xp_cmdshell ma wady bezpieczeństwa, a mimo to wymaga wielu analiz. To kłopotliwe. Opcja nr 2 jest elegancka. I jest to czyste rozwiązanie t-sql, które prawie zawsze wolę. Oto dwa przykładowe zapytania dla opcji nr 2:

SELECT c.local_net_address
FROM sys.dm_exec_connections AS c
WHERE c.session_id = @@SPID;

SELECT TOP(1) c.local_net_address
FROM sys.dm_exec_connections AS c
WHERE c.local_net_address IS NOT NULL;

Czasami jednak żadne z powyższych zapytań nie działa. Zapytanie nr 1 zwraca NULL, jeśli masz połączenie za pośrednictwem pamięci współużytkowanej (jesteś zalogowany i uruchamiasz SSMS na hoście SQL). Zapytanie nr 2 może nic nie zwrócić, jeśli nie ma połączeń korzystających z protokołu pamięci niedzielonej. Ten scenariusz jest prawdopodobny w przypadku połączenia z nowo zainstalowanym wystąpieniem SQL. Rozwiązanie? Wymuś połączenie przez TCP / IP. Aby to zrobić, utwórz nowe połączenie w programie SSMS i użyj przedrostka „tcp:” z nazwą serwera. Następnie ponownie uruchom dowolne zapytanie, a otrzymasz adres IP.

SSMS - Połącz z aparatem bazy danych

Dave Mason
źródło
To da ipv4 ... czy możemy dostać ipv6?
Shikhil Bhalla
8

- Wypróbuj ten skrypt, który działa na moje potrzeby. Sformatuj ponownie, aby to przeczytać.

SELECT  
SERVERPROPERTY('ComputerNamePhysicalNetBios')  as 'Is_Current_Owner'
    ,SERVERPROPERTY('MachineName')  as 'MachineName'
    ,case when @@ServiceName = 
    Right (@@Servername,len(@@ServiceName)) then @@Servername 
      else @@servername +' \ ' + @@Servicename
      end as '@@Servername \ Servicename',  
    CONNECTIONPROPERTY('net_transport') AS net_transport,
    CONNECTIONPROPERTY('local_tcp_port') AS local_tcp_port,
    dec.local_tcp_port,
    CONNECTIONPROPERTY('local_net_address') AS local_net_address,
    dec.local_net_address as 'dec.local_net_address'
    FROM sys.dm_exec_connections AS dec
    WHERE dec.session_id = @@SPID;
Hank Freeman
źródło
Dzięki. Wystarczy zaktualizować dec.local_tcp_port jako „dec.local_tcp_port”, aby użyć go w funkcji. W przeciwnym razie narzeka, że ​​istnieją dwie kolumny o nazwie local_tcp_port.
Steven Van Dorpe
7

możesz użyć zapytania z linii poleceń i wykonać w mssql:

exec xp_cmdshell 'ipconfig'
Ranjana Ghimire
źródło
2
To zadziała tylko wtedy, gdy xp_cmdshelljest włączone w konfiguracji bezpieczeństwa serwera
Javasick
4
select @@servername
Pseudo masochista
źródło
2

Prostszym sposobem uzyskania nazwy komputera bez \ InstanceName jest:

SELECT SERVERPROPERTY('MachineName')
GilM
źródło
1

Wiem, że to stary post, ale być może to rozwiązanie przyda się, gdy chcesz pobrać adres IP i port TCP z połączenia Shared Memory (np. Ze skryptu uruchamianego w SSMS lokalnie na serwerze). Kluczem jest otwarcie dodatkowego połączenia z serwerem SQL za pomocą OPENROWSET, w którym należy określić „tcp:” w ciągu połączenia. Pozostała część kodu to po prostu budowanie dynamicznego kodu SQL, aby obejść ograniczenie OPENROWSET polegające na niemożności przyjęcia zmiennych jako parametrów.

DECLARE @ip_address       varchar(15)
DECLARE @tcp_port         int 
DECLARE @connectionstring nvarchar(max) 
DECLARE @parm_definition  nvarchar(max)
DECLARE @command          nvarchar(max)

SET @connectionstring = N'Server=tcp:' + @@SERVERNAME + ';Trusted_Connection=yes;'
SET @parm_definition  = N'@ip_address_OUT varchar(15) OUTPUT
                        , @tcp_port_OUT   int         OUTPUT';

SET @command          = N'SELECT  @ip_address_OUT = a.local_net_address,
                                  @tcp_port_OUT   = a.local_tcp_port
                          FROM OPENROWSET(''SQLNCLI''
                                 , ''' + @connectionstring + '''
                                 , ''SELECT local_net_address
                                          , local_tcp_port
                                     FROM sys.dm_exec_connections
                                     WHERE session_id = @@spid
                                   '') as a'

EXEC SP_executeSQL @command
                 , @parm_definition
                 , @ip_address_OUT = @ip_address OUTPUT
                 , @tcp_port_OUT   = @tcp_port OUTPUT;


SELECT @ip_address, @tcp_port
Bert Van Landeghem
źródło
Zwracam tylko uwagę, że wymaga Ad Hoc Distributed Queriesto włączenia.
Dan