SQL - запрос на получение IP-адреса сервера

97

Есть ли в SQL Server 2005 запрос, который я могу использовать для получения IP-адреса или имени сервера?

Сейбар
источник
При подключении к SQL с использованием прослушивателя AG кажется, что CONNECTIONPROPERTY ('local_net_address') возвращает IP-адрес прослушивателя вместо IP-адреса сервера.
brian beuning 01

Ответы:

148
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 

Код здесь даст вам IP-адрес;

Это будет работать для запроса удаленного клиента к SQL 2008 и новее.

Если у вас разрешены соединения с общей памятью, то запуск выше на самом сервере даст вам

  • "Общая память" как значение для 'net_transport', и
  • NULL для 'local_net_address' и
  • ' <local machine>' будет отображаться в 'client_net_address'.

client_net_address - это адрес компьютера, с которого был отправлен запрос, тогда как local_net_address - это сервер SQL (таким образом, NULL по соединениям с общей памятью), и адрес, который вы дадите кому-то, если он не сможет использовать NetBios сервера. имя или полное доменное имя по какой-то причине.

Я категорически не советую использовать этот ответ . Включение оболочки - очень плохая идея для производственного SQL Server.

Джефф Маззи
источник
3
Хороший ответ, за исключением того, что я получаю отрицательный номер порта (-15736) для порта, который должен быть 49800. Итак, если отрицательный, безопасно ли просто добавить 65536?
crokusek
Если кто-то захочет удаленно войти на SQL-сервер моего компьютера, какой IP ему дать? local_net_address или client_net_address?
Дэвид Блейн
@rene - рассматривал это, но сам исходный ответ верен (для SQL2008 + и удаленных подключений), поэтому просто подумал, чтобы уточнить, что означают параметры ConnectionProperty. Конечно, ответ Криса Леонарда (dm_exec_connections) также верен по тем же причинам. Если вы думаете, что мое приложение лучше использовать как отдельный ответ, чем не стесняйтесь делать это так :) Я не отвечал на вопросы какое-то время, поэтому политика и правила здесь могли измениться (сейчас прочту их ...)
Мартин С. Stoller
Причина добавления в соответствии с " stackoverflow.com/help/editing ": чтобы прояснить значение сообщения (без изменения этого значения).
Мартин С. Столлер,
1
@ MartinS.Stoller Я отредактировал ваше дополнение для удобства. Пожалуйста, проверьте, ничего ли я не пропустил.
Рене
33

Вы можете получить [имя хоста] \ [имя экземпляра]:

SELECT @@SERVERNAME;

Чтобы получить только имя хоста, когда у вас есть формат имя хоста \ имя экземпляра:

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

В качестве альтернативы, как указал @GilM:

SELECT SERVERPROPERTY('MachineName')

Вы можете получить фактический IP-адрес, используя это:

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

Источник сценария SQL .

Брайан Р. Бонди
источник
21

Сервер может иметь несколько IP-адресов, которые он прослушивает. Если вашему соединению предоставлено разрешение сервера VIEW SERVER STATE, вы можете запустить этот запрос, чтобы получить адрес, который вы подключили к SQL Server:

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

Это решение не требует, чтобы вы запускали оболочку ОС через xp_cmdshell, это метод, который должен быть отключен (или, по крайней мере, строго защищен) на рабочем сервере. Может потребоваться предоставить VIEW SERVER STATE соответствующему имени входа, но это гораздо меньшая угроза безопасности, чем запуск xp_cmdshell.

Техника, упомянутая GilM для имени сервера, является предпочтительной:

SELECT SERVERPROPERTY(N'MachineName');
Скай --- капитан
источник
Спасибо за этот ответ ... Я считаю, что это верный способ определения IP-адреса сервера, если вам нужно проверить его со стороны подключения клиента, особенно если клиентское подключение было установлено с помощью строки подключения, содержащей псевдоним SQL или названной экземпляр как источник данных.
Родольфо Г.
11

Большинство решений для получения IP-адреса через t-sql попадают в эти два лагеря:

  1. Запуск с ipconfig.exeпомощью xp_cmdshellи разобрать вывод

  2. Запрос DMV sys.dm_exec_connections

Я не фанат варианта №1. Включение xp_cmdshell имеет недостатки безопасности, и в любом случае требуется много анализа. Это громоздко. Вариант №2 элегантен. И это чистое решение t-sql, которое я почти всегда предпочитаю. Вот два примера запроса для варианта №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;

Однако иногда ни один из приведенных выше запросов не работает. Запрос №1 возвращает NULL, если вы подключены через общую память (вошли в систему и используете SSMS на узле SQL). Запрос №2 может ничего не вернуть, если нет соединений, использующих протокол без общей памяти. Этот сценарий вероятен при подключении к недавно установленному экземпляру SQL. Решение? Установите соединение через TCP / IP. Для этого создайте новое соединение в SSMS и используйте префикс «tcp:» с именем сервера. Затем повторно запустите любой запрос, и вы получите IP-адрес.

SSMS - подключение к ядру СУБД

Дэйв Мейсон
источник
Это даст ipv4 .. мы можем получить ipv6?
Шикхил Бхалла
8

- Попробуйте этот сценарий, он подходит для моих нужд. Переформатируйте, чтобы прочитать.

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;
Хэнк Фриман
источник
Спасибо. Просто нужно было обновить dec.local_tcp_port как dec.local_tcp_port, чтобы использовать его в функции. В противном случае он жалуется, что есть два столбца с именем local_tcp_port.
Стивен Ван Дорп,
7

вы можете использовать запрос командной строки и выполнить его в mssql:

exec xp_cmdshell 'ipconfig'
Ранджана Гимире
источник
2
Это будет работать, только если xp_cmdshellвключено в конфигурации безопасности сервера
Javasick
2

Более простой способ получить имя машины без \ InstanceName:

SELECT SERVERPROPERTY('MachineName')
GilM
источник
1

Я знаю, что это старый пост, но, возможно, это решение может быть полезно, когда вы хотите получить IP-адрес и порт TCP из соединения с общей памятью (например, из сценария, запущенного в SSMS локально на сервере). Ключ состоит в том, чтобы открыть вторичное соединение с вашим SQL Server с помощью OPENROWSET, в котором вы указываете «tcp:» в строке подключения. Остальная часть кода просто создает динамический SQL, чтобы обойти ограничение OPENROWSET, заключающееся в невозможности принимать переменные в качестве параметров.

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
Берт Ван Ландегем
источник
Просто отмечу, что для этого нужно Ad Hoc Distributed Queriesвключить.
Дэн