SQL - consulta para obter o endereço IP do servidor

94

Existe uma consulta no SQL Server 2005 que posso usar para obter o IP ou nome do servidor?

Seibar
fonte
Ao conectar ao SQL usando um ouvinte AG, parece que CONNECTIONPROPERTY ('local_net_address') retorna o IP do ouvinte em vez do IP do servidor.
brian beuning 01 de

Respostas:

145
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 

O código aqui fornecerá o endereço IP;

Isso funcionará para uma solicitação de cliente remoto para SQL 2008 e mais recente.

Se você tiver conexões de memória compartilhada permitidas, a execução acima no próprio servidor lhe dará

  • "Memória compartilhada" como o valor para 'net_transport', e
  • NULL para 'local_net_address', e
  • ' <local machine>' será mostrado em 'client_net_address'.

'client_net_address' é o endereço do computador de onde a solicitação se originou, enquanto 'local_net_address' seria o servidor SQL (portanto, NULL em conexões de memória compartilhada) e o endereço que você daria a alguém se eles não pudessem usar o NetBios do servidor nome ou FQDN por algum motivo.

Aconselho fortemente contra o uso desta resposta . Habilitar o shell out é uma ideia muito ruim em um SQL Server de produção.

Jeff Muzzy
fonte
3
Boa resposta, exceto que estou obtendo um número de porta negativo (-15736) para uma porta que deveria ser 49800. Então, se negativo, é seguro apenas adicionar 65536?
crokusek
Se alguém quiser fazer login remotamente no servidor SQL do meu computador, qual IP devo fornecer a ele? local_net_address ou client_net_address?
David Blaine
@rene - estava considerando isso, mas a resposta original em si está correta (para SQL2008 + e conexões remotas), então pensei em esclarecer o que os parâmetros ConnectionProperty significavam. Claro que a resposta de Chris Leonard (dm_exec_connections) também está correta, pelos mesmos motivos. Se você acha que meu adendo é melhor como uma resposta separada do que sinta-se à vontade para torná-lo assim :) Faz um tempo que não respondo às perguntas, então a política e as regras aqui podem ter mudado (irei lê-las agora ...)
Martin S. Stoller
Motivo do addenum conforme " stackoverflow.com/help/editing ": Para esclarecer o significado da postagem (sem alterar esse significado).
Martin S. Stoller
1
@ MartinS.Stoller Eu editei sua adição para facilitar a leitura. Verifique se não perdi nada.
René
33

Você pode obter o [nome do host] \ [nome da instância] por:

SELECT @@SERVERNAME;

Para obter apenas o nome do host quando você tiver o formato nome do host \ nome da instância:

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

Alternativamente, como @GilM apontou:

SELECT SERVERPROPERTY('MachineName')

Você pode obter o endereço IP real usando:

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

Fonte do script SQL .

Brian R. Bondy
fonte
19

O servidor pode ter vários endereços IP em que está escutando. Se sua conexão tiver a permissão de servidor VIEW SERVER STATE concedida a ela, você pode executar esta consulta para obter o endereço que você conectou ao SQL Server:

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

Esta solução não requer que você forneça ao SO via xp_cmdshell, que é uma técnica que deve ser desabilitada (ou pelo menos estritamente protegida) em um servidor de produção. Pode exigir que você conceda VIEW SERVER STATE ao login apropriado, mas esse é um risco de segurança muito menor do que executar xp_cmdshell.

A técnica mencionada por GilM para o nome do servidor é a preferida:

SELECT SERVERPROPERTY(N'MachineName');
skye --- capitão
fonte
Obrigado por esta resposta ... Acredito que esta seja a verdadeira maneira de determinar o endereço IP do servidor se você precisar verificá-lo do lado da conexão do cliente, especialmente se a conexão do cliente foi estabelecida com uma string de conexão que continha um alias SQL ou nome instância como uma fonte de dados.
Rodolfo G.
11

A maioria das soluções para obter o endereço IP via t-sql se enquadra nestes dois campos:

  1. Execute ipconfig.exevia xp_cmdshelle analisar a saída

  2. Consultar DMV sys.dm_exec_connections

Não sou fã da opção nº 1. Habilitar xp_cmdshell tem desvantagens de segurança e, de qualquer maneira, há muita análise envolvida. Isso é complicado. A opção 2 é elegante. E é uma solução t-sql pura, que quase sempre prefiro. Aqui estão dois exemplos de consultas para a opção 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;

Às vezes, nenhuma das consultas acima funciona. A consulta # 1 retorna NULL se você estiver conectado pela memória compartilhada (conectado e executando o SSMS no host SQL). A consulta # 2 pode não retornar nada se não houver conexões usando um protocolo de memória não compartilhada. Este cenário é provável quando conectado a uma instância SQL recém-instalada. A solução? Força uma conexão por TCP / IP. Para fazer isso, crie uma nova conexão no SSMS e use o prefixo "tcp:" com o nome do servidor. Em seguida, execute novamente qualquer consulta e você obterá o endereço IP.

SSMS - conectar ao mecanismo de banco de dados

Dave Mason
fonte
Isso vai dar ipv4 .. podemos obter ipv6?
Shikhil Bhalla
7

você pode usar a consulta de linha de comando e executar em mssql:

exec xp_cmdshell 'ipconfig'
Ranjana Ghimire
fonte
1
Isso funcionará apenas se xp_cmdshellestiver habilitado na configuração de segurança do servidor
Javasick
7

- Experimente este script que atende às minhas necessidades. Reformate para ler.

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
fonte
Obrigado. Só tive que atualizar dec.local_tcp_port como 'dec.local_tcp_port' para usá-lo em uma função. Caso contrário, ele reclama que há duas colunas chamadas local_tcp_port.
Steven Van Dorpe
4
select @@servername
Pseudo Masoquista
fonte
2

Uma maneira mais simples de obter o nome da máquina sem o \ InstanceName é:

SELECT SERVERPROPERTY('MachineName')
GilM
fonte
1

Eu sei que este é um post antigo, mas talvez esta solução possa ser útil quando você deseja recuperar o endereço IP e a porta TCP de uma conexão de memória compartilhada (por exemplo, de um script executado em SSMS localmente no servidor). A chave é abrir uma conexão secundária com seu SQL Server usando OPENROWSET, no qual você especifica 'tcp:' em sua string de conexão. O resto do código é meramente construir SQL dinâmico para contornar a limitação do OPENROWSET de não ser capaz de tomar variáveis ​​como seus parâmetros.

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
fonte
Apenas observando que isso precisa Ad Hoc Distributed Queriesser ativado.
Dan