SQL - Запит на отримання IP-адреси сервера


95

Чи є в SQL Server 2005 запит, за допомогою якого я можу отримати IP-адресу або ім’я сервера?


При підключенні до SQL за допомогою прослуховувача AG виявляється, що CONNECTIONPROPERTY ('local_net_address') повертає IP прослуховувача замість IP сервера.
Брайан Бінінг,

Відповіді:


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 

Код тут дасть вам 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

Причина addenum як на « stackoverflow.com/help/editing »: Для того, щоб роз'яснити сенс посту (без змінити цю установку).
Martin S. Stoller

1
@ MartinS.Stoller Я відредагував ваше доповнення для готовності. Будь ласка, перевірте, чи я нічого не пропустив.
Rene

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 .


19

Сервер може мати кілька 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

Я не фанат варіанту No1. Увімкнення xp_cmdshell має недоліки безпеки, і в будь-якому випадку йде багато аналізу. Це громіздко. Варіант No2 - елегантний. І це чисте рішення 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?
Shikhil Bhalla


7

Ви можете використовувати запит командного рядка та виконати в mssql:

exec xp_cmdshell 'ipconfig'

1
Це спрацює, лише якщо xp_cmdshellввімкнено в конфігурації безпеки сервера
Javasick

7

- Спробуйте цей сценарій, який працює на мої потреби. Переформатуйте, щоб прочитати його.

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.
Стівен Ван Дорпе


2

Більш простим способом отримати назву машини без \ InstanceName є:

SELECT SERVERPROPERTY('MachineName')

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ввімкнути.
Ден,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.