SQL - Sunucunun IP adresini almak için sorgu


99

SQL Server 2005'te sunucunun IP'sini veya adını almak için kullanabileceğim bir sorgu var mı?


Bir AG dinleyicisi kullanarak SQL'e bağlanırken, CONNECTIONPROPERTY ('local_net_address'), sunucu IP'si yerine dinleyici IP'sini döndürür.
brian beuning

Yanıtlar:


150
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 

Buradaki kod size IP Adresini verecektir;

Bu, SQL 2008 ve daha yeni bir uzak istemci isteği için çalışacaktır.

Paylaşılan Bellek bağlantılarına izin veriliyorsa, sunucunun üzerinde çalıştırmak size

  • "Net_transport" değeri olarak "Paylaşılan Bellek" ve
  • 'Local_net_address' için NULL ve
  • ' <local machine>', 'client_net_address'de gösterilecektir.

'client_net_address', isteğin kaynaklandığı bilgisayarın adresidir, oysa 'local_net_address' SQL sunucusu (dolayısıyla Paylaşılan Bellek bağlantıları üzerinden NULL) ve sunucunun NetBio'larını kullanamayan birine vereceğiniz adres olacaktır. bir nedenle adı veya FQDN.

Bu cevabı kullanmamanızı şiddetle tavsiye ediyorum . Kabuğun çıkışını etkinleştirmek, üretim SQL Sunucusunda çok kötü bir fikirdir.


3
49800 olması gereken bir bağlantı noktası için negatif bir bağlantı noktası numarası (-15736) almam dışında güzel yanıt. Yani negatifse, sadece 65536 eklemek güvenli midir?
crokusek

Birisi bilgisayarımın SQL sunucusuna uzaktan oturum açmak isterse, ona hangi IP'yi vereceğim? local_net_address veya client_net_address?
david blaine

@rene - bunu düşünüyordu, ancak orijinal cevabın kendisi doğrudur (SQL2008 + ve uzak bağlantılar için), bu yüzden ConnectionProperty parametrelerinin ne anlama geldiğini açıklığa kavuşturmak için düşündüm. Elbette Chris Leonard'ın yanıtı (dm_exec_connections) da aynı nedenlerle doğrudur. Zeyilnamemin ayrı bir cevap olduğunu düşünüyorsanız, bunu yapmaktan çekinmeyin :) Bir süredir soruları yanıtlamadım, bu yüzden buradaki politika ve kurallar değişmiş olabilir (şimdi onları okuyacağım ...)
Martin S. Stoller

" Stackoverflow.com/help/editing " uyarınca addenum nedeni: Gönderinin anlamını netleştirmek için (bu anlamı değiştirmeden).
Martin S. Stoller

1
@ MartinS.Stoller Eklemenizi okunabilirlik için düzenledim. Lütfen hiçbir şeyi kaçırmadığımı kontrol edin.
rene

35

[Hostname] \ [instancename] 'ı şu şekilde alabilirsiniz:

SELECT @@SERVERNAME;

Hostname \ instance name formatınız olduğunda sadece hostname almak için:

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

Alternatif olarak @GilM'in belirttiği gibi:

SELECT SERVERPROPERTY('MachineName')

Bunu kullanarak gerçek IP adresini alabilirsiniz:

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 komut dosyasının kaynağı .


21

Sunucunun dinlediği birden çok IP adresi olabilir. Bağlantınız kendisine verilmiş SERVER DURUMUNU GÖRÜNTÜLE sunucu iznine sahipse, SQL Server'a bağladığınız adresi almak için bu sorguyu çalıştırabilirsiniz:

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

Bu çözüm, bir üretim sunucusunda devre dışı bırakılması (veya en azından kesinlikle güvenli hale getirilmesi) gereken bir teknik olan xp_cmdshell aracılığıyla OS'ye kabuk göndermenizi gerektirmez. Uygun oturuma VIEW SERVER STATE vermenizi gerektirebilir, ancak bu xp_cmdshell'i çalıştırmaktan çok daha küçük bir güvenlik riskidir.

GilM tarafından sunucu adı için bahsedilen teknik tercih edilen tekniktir:

SELECT SERVERPROPERTY(N'MachineName');

Bu yanıt için teşekkürler ... İstemcinin bağlantı tarafından doğrulamanız gerekiyorsa, özellikle istemcinin bağlantısı bir SQL takma adı içeren veya adlandırılmış bir bağlantı dizesiyle kurulmuşsa, sunucunun ip adresini belirlemenin gerçek yolu olduğuna inanıyorum. bir veri kaynağı olarak örnek.
Rodolfo G.

11

IP adresini t-sql aracılığıyla almak için çoğu çözüm bu iki gruba dahildir:

  1. Çıkış ipconfig.exeüzerinden çalıştır xp_cmdshellve ayrıştır

  2. DMV'yi Sorgula sys.dm_exec_connections

1. seçeneğin hayranı değilim. Xp_cmdshell'i etkinleştirmenin güvenlik dezavantajları vardır ve yine de birçok ayrıştırma söz konusudur. Bu çok zahmetli. 2. Seçenek zariftir. Ve neredeyse her zaman tercih ettiğim saf bir t-sql çözümü. Aşağıda 2. seçenek için iki örnek sorgu verilmiştir:

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;

Bazen yukarıdaki sorguların hiçbiri işe yaramaz. Sorgu # 1, Paylaşılan Bellek üzerinden bağlanırsanız (oturum açtıysanız ve SQL ana bilgisayarında SSMS çalıştırıyorsanız) NULL döndürür. Paylaşılmayan Bellek protokolünü kullanan bağlantı yoksa, Sorgu # 2 hiçbir şey döndürmeyebilir. Bu senaryo, yeni kurulan bir SQL örneğine bağlanıldığında olasıdır. Çözüm? TCP / IP üzerinden bir bağlantıyı zorlayın. Bunu yapmak için, SSMS'de yeni bir bağlantı oluşturun ve sunucu adıyla birlikte "tcp:" önekini kullanın. Daha sonra her iki sorguyu yeniden çalıştırın ve IP adresini alacaksınız.

SSMS - Veritabanı Motoruna Bağlan


Bu ipv4 verecek .. ipv6 alabilir miyiz?
Shikhil Bhalla


8

- Bu komut dosyasını deneyin, benim ihtiyaçlarıma göre çalışır. Okumak için yeniden biçimlendirin.

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;

Teşekkürler. Bir işlevde kullanmak için dec.local_tcp_port'u 'dec.local_tcp_port' olarak güncellememiz gerekiyordu. Aksi takdirde local_tcp_port adlı iki sütun olduğundan şikayet eder.
Steven Van Dorpe

7

komut satırı sorgusunu kullanabilir ve mssql'de çalıştırabilirsiniz:

exec xp_cmdshell 'ipconfig'

2
Bu yalnızca xp_cmdshellsunucu güvenlik yapılandırmasında etkinleştirilmişse çalışır
Javasick


2

\ ÖrnekAdı olmadan makine adını almanın daha basit bir yolu şudur:

SELECT SERVERPROPERTY('MachineName')

1

Bunun eski bir gönderi olduğunu biliyorum, ancak IP adresini ve TCP bağlantı noktasını Paylaşılan Bellek bağlantısından (örneğin, sunucuda yerel olarak SSMS'de çalıştırılan bir komut dizisinden) almak istediğinizde bu çözüm faydalı olabilir. Anahtar, OPENROWSET kullanarak SQL Sunucunuza ikincil bir bağlantı açmaktır, burada bağlantı dizenizde 'tcp:' belirtirsiniz. Kodun geri kalanı, OPENROWSET'in değişkenleri parametre olarak alamama sınırlamasını aşmak için yalnızca dinamik SQL oluşturuyor.

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

Sadece bunun Ad Hoc Distributed Queriesaçılması gerektiğini belirterek .
Dan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.