SQL - Truy vấn để lấy địa chỉ IP của máy chủ


95

Có truy vấn nào trong SQL Server 2005 mà tôi có thể sử dụng để lấy IP hoặc tên của máy chủ không?


Khi kết nối với SQL bằng trình nghe AG, nó xuất hiện CONNECTIONPROPERTY ('local_net_address') trả về IP của trình nghe thay vì IP của máy chủ.
brian beuning

Câu trả lời:


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 

Mã ở đây Sẽ cung cấp cho bạn Địa chỉ IP;

Điều này sẽ hoạt động cho một yêu cầu máy khách từ xa cho SQL 2008 và mới hơn.

Nếu bạn đã cho phép kết nối Bộ nhớ dùng chung, thì việc chạy ở trên trên chính máy chủ sẽ cung cấp cho bạn

  • "Bộ nhớ dùng chung" làm giá trị cho 'net_transport' và
  • NULL cho 'local_net_address' và
  • ' <local machine>' sẽ được hiển thị trong 'client_net_address'.

'client_net_address' là địa chỉ của máy tính mà yêu cầu bắt nguồn từ đó, trong khi 'local_net_address' sẽ là máy chủ SQL (do đó NULL qua các kết nối Bộ nhớ dùng chung) và địa chỉ bạn sẽ cung cấp cho ai đó nếu họ không thể sử dụng NetBios của máy chủ tên hoặc FQDN vì một số lý do.

Tôi khuyên bạn không nên sử dụng câu trả lời này . Bật trình bao là một ý tưởng rất tồi trên SQL Server sản xuất.


3
Câu trả lời hay, ngoại trừ việc tôi nhận được số cổng âm (-15736) cho một cổng phải là 49800. Vì vậy, nếu tiêu cực thì chỉ cần thêm 65536 có an toàn không?
crokusek

Nếu ai đó muốn đăng nhập từ xa vào máy chủ SQL của máy tính của tôi, thì tôi phải cấp cho anh ta IP nào? local_net_address hay client_net_address?
david blaine

@rene - đang xem xét nó, nhưng bản thân câu trả lời ban đầu là đúng (đối với SQL2008 + và các kết nối từ xa) vì vậy chỉ cần suy nghĩ để làm rõ ý nghĩa của các thông số ConnectionProperty. Tất nhiên câu trả lời của Chris Leonard (dm_exec_connections) cũng đúng, vì những lý do tương tự. Nếu bạn nghĩ rằng phụ lục của tôi tốt hơn là câu trả lời riêng lẻ hơn là thoải mái làm như vậy :) Tôi đã không trả lời câu hỏi trong một thời gian, vì vậy chính sách và quy tắc ở đây có thể đã thay đổi (sẽ đọc chúng ngay bây giờ ...)
Martin S. Stoller

Lý do addenum theo " stackoverflow.com/help/editing ": Để ​​làm rõ ý nghĩa của bài đăng (mà không thay đổi ý nghĩa đó).
Martin S. Stoller

1
@ MartinS.Stoller Tôi đã chỉnh sửa phần bổ sung của bạn để dễ đọc. Vui lòng kiểm tra xem tôi có bỏ sót gì không.
René

33

Bạn có thể lấy [tên máy chủ] \ [tên cá thể] bằng cách:

SELECT @@SERVERNAME;

Để chỉ lấy tên máy chủ khi bạn có tên máy chủ \ định dạng tên phiên bản:

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

Ngoài ra, như @GilM đã chỉ ra:

SELECT SERVERPROPERTY('MachineName')

Bạn có thể lấy địa chỉ IP thực bằng cách sử dụng:

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

Nguồn của tập lệnh SQL .


19

Máy chủ có thể có nhiều địa chỉ IP mà nó đang nghe. Nếu kết nối của bạn được cấp quyền máy chủ VIEW SERVER STATE, bạn có thể chạy truy vấn này để lấy địa chỉ bạn đã kết nối với SQL Server:

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

Giải pháp này không yêu cầu bạn chuyển sang hệ điều hành thông qua xp_cmdshell, đây là một kỹ thuật cần được vô hiệu hóa (hoặc ít nhất là được bảo mật nghiêm ngặt) trên máy chủ sản xuất. Nó có thể yêu cầu bạn cấp VIEW SERVER STATE cho thông tin đăng nhập thích hợp, nhưng đó là rủi ro bảo mật nhỏ hơn nhiều so với việc chạy xp_cmdshell.

Kỹ thuật được GilM đề cập cho tên máy chủ là kỹ thuật được ưu tiên:

SELECT SERVERPROPERTY(N'MachineName');

Cảm ơn phản hồi này ... Tôi tin rằng đây là cách thực sự để xác định địa chỉ ip của máy chủ nếu bạn cần xác minh nó từ phía kết nối của máy khách, đặc biệt nếu kết nối của máy khách được thiết lập bằng chuỗi kết nối có chứa bí danh SQL hoặc được đặt tên ví dụ như một nguồn dữ liệu.
Rodolfo G.

11

Hầu hết các giải pháp để lấy địa chỉ IP qua t-sql rơi vào hai nhóm sau:

  1. Chạy ipconfig.exequa xp_cmdshellvà phân tích cú pháp đầu ra

  2. Truy vấn DMV sys.dm_exec_connections

Tôi không phải là người thích lựa chọn số 1. Kích hoạt xp_cmdshell có những hạn chế về bảo mật và dù sao cũng có rất nhiều phân tích cú pháp. Thật là rườm rà. Tùy chọn số 2 là thanh lịch. Và đó là một giải pháp t-sql thuần túy, mà tôi hầu như luôn thích hơn. Đây là hai truy vấn mẫu cho tùy chọn số 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;

Tuy nhiên, đôi khi cả hai truy vấn trên đều không hoạt động. Truy vấn số 1 trả về NULL nếu bạn được kết nối qua Bộ nhớ dùng chung (đã đăng nhập và chạy SSMS trên máy chủ SQL). Truy vấn số 2 có thể không trả về gì nếu không có kết nối nào sử dụng giao thức Bộ nhớ không dùng chung. Trường hợp này có thể xảy ra khi được kết nối với phiên bản SQL mới được cài đặt. Giải pháp? Buộc kết nối qua TCP / IP. Để thực hiện việc này, hãy tạo một kết nối mới trong SSMS và sử dụng tiền tố "tcp:" với tên máy chủ. Sau đó, chạy lại một trong hai truy vấn và bạn sẽ nhận được địa chỉ IP.

SSMS - Kết nối với Cơ sở dữ liệu


Điều này sẽ cung cấp cho ipv4 .. chúng ta có thể nhận được ipv6?
Shikhil Bhalla


7

bạn có thể sử dụng truy vấn dòng lệnh và thực thi trong mssql:

exec xp_cmdshell 'ipconfig'

1
Điều đó sẽ chỉ hoạt động nếu xp_cmdshellđược bật trong cấu hình bảo mật máy chủ
Javasick

7

--Hãy thử tập lệnh này, nó phù hợp với nhu cầu của tôi. Định dạng lại để đọc nó.

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;

Cảm ơn. Chỉ cần cập nhật dec.local_tcp_port là 'dec.local_tcp_port' để sử dụng nó trong một hàm. Nếu không, nó phàn nàn rằng có hai cột có tên local_tcp_port.
Steven Van Dorpe


2

Một cách đơn giản hơn để lấy tên máy mà không có \ InstanceName là:

SELECT SERVERPROPERTY('MachineName')

1

Tôi biết đây là một bài viết cũ, nhưng có lẽ giải pháp này có thể hữu ích khi bạn muốn truy xuất địa chỉ IP và cổng TCP từ kết nối Bộ nhớ dùng chung (ví dụ: từ một tập lệnh chạy trong SSMS cục bộ trên máy chủ). Chìa khóa là mở một kết nối phụ tới SQL Server của bạn bằng OPENROWSET, trong đó bạn chỉ định 'tcp:' trong chuỗi kết nối của mình. Phần còn lại của đoạn mã chỉ đơn thuần là xây dựng SQL động để khắc phục hạn chế của OPENROWSET là không thể lấy các biến làm tham số của nó.

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

Chỉ cần lưu ý rằng điều này yêu cầu Ad Hoc Distributed Queriesđược bật.
Dan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.