SQL-查询以获取服务器的IP地址


95

我可以使用SQL Server 2005中的查询来获取服务器的IP或名称吗?


使用AG侦听器连接到SQL时,似乎CONNECTIONPROPERTY('local_net_address')返回侦听器IP,而不是服务器IP。
brian beuning

Answers:


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”的值,并且
  • “ local_net_address”为NULL,并且
  • <local machine>”将显示在“ client_net_address”中。

“ client_net_address”是请求所源自的计算机的地址,而“ local_net_address”将是SQL Server(因此,“共享内存”连接为NULL),以及如果某人无法使用服务器的NetBios,则将其提供给某人的地址名称或FQDN出于某种原因。

我强烈建议不要使用此答案。在生产SQL Server上,启用外壳程序是一个非常糟糕的主意。


3
很好的答案,除了我得到的端口号应该为49800的端口号为负(-15736)。因此,如果为负数,只需添加65536是安全的吗?
crokusek

如果有人想远程登录到我的计算机的SQL服务器,那么我应该给他提供哪个IP?local_net_address或client_net_address?
大卫·布莱恩

@rene-正在考虑它,但是原始答案本身是正确的(对于SQL2008 +和远程连接),因此只是想弄清楚ConnectionProperty参数的含义。当然,出于相同的原因,克里斯·伦纳德(Chris Leonard)的答案(dm_exec_connections)也是正确的。如果您认为我的附录最好作为单独的答案而不是随意这样做:)一段时间没有回答问题了,所以这里的政策和规则可能已经改变(现在将继续阅读...)
马丁·S。斯托勒2015年

根据“ stackoverflow.com/help/editing ”添加附件的原因:阐明帖子的含义(不更改该含义)。
Martin S. Stoller

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脚本的来源


19

服务器可能有多个正在监听的IP地址。如果您的连接具有授予的“查看服务器状态”服务器权限,则可以运行此查询以获取已连接到SQL Server的地址:

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

此解决方案不需要您通过xp_cmdshell将其外壳到OS,这是应该在生产服务器上禁用(或至少严格保护)的技术。可能需要您向VIEW SERVER STATE授予适当的登录名,但是,与运行xp_cmdshell相比,这具有很小的安全风险。

首选的方法是GilM提到的服务器名称技术:

SELECT SERVERPROPERTY(N'MachineName');

感谢您的答复...如果您需要从客户端的连接端进行验证,我相信这是确定服务器ip地址的正确方法,特别是如果客户端的连接是使用包含SQL别名或已命名的连接字符串建立的实例作为数据源。
Rodolfo G.

11

通过t-sql获取IP地址的大多数解决方案都属于以下两个阵营:

  1. ipconfig.exe通过运行xp_cmdshell并解析输出

  2. 查询DMV sys.dm_exec_connections

我不喜欢第一种选择。启用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;

有时,以上两种查询都不起作用。如果您是通过共享内存连接(在SQL主机上登录并运行SSMS),则查询1将返回NULL。如果没有使用非共享内存协议的连接,则查询#2可能不返回任何内容。连接到新安装的SQL实例时,可能会出现这种情况。解决方案?强制通过TCP / IP进行连接。为此,请在SSMS中创建一个新连接,并在服务器名称中使用“ tcp:”前缀。然后重新运行任一查询,您将获得IP地址。

SSMS-连接到数据库引擎


这将给ipv4 ..我们可以得到ipv6吗?
Shikhil Bhalla



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

我知道这是一篇过时的文章,但是当您要从“共享内存”连接(例如,从服务器本地在SSMS中运行的脚本)中检索IP地址和TCP端口时,此解决方案可能有用。关键是使用OPENROWSET打开到SQL Server的辅助连接,在该连接中您可以在连接字符串中指定“ 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打开。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.