มีแบบสอบถามใน SQL Server 2005 ที่ฉันสามารถใช้เพื่อรับ IP หรือชื่อของเซิร์ฟเวอร์ได้หรือไม่
มีแบบสอบถามใน SQL Server 2005 ที่ฉันสามารถใช้เพื่อรับ IP หรือชื่อของเซิร์ฟเวอร์ได้หรือไม่
คำตอบ:
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 และใหม่กว่า
หากคุณอนุญาตการเชื่อมต่อหน่วยความจำที่ใช้ร่วมกันการทำงานด้านบนบนเซิร์ฟเวอร์จะให้คุณ
<local machine>
' จะแสดงใน 'client_net_address''client_net_address' คือที่อยู่ของคอมพิวเตอร์ที่มีการร้องขอในขณะที่ 'local_net_address' จะเป็นเซิร์ฟเวอร์ SQL (ดังนั้นจึงเป็น NULL บนการเชื่อมต่อหน่วยความจำที่ใช้ร่วมกัน) และที่อยู่ที่คุณจะให้กับบุคคลอื่นหากพวกเขาไม่สามารถใช้ NetBios ของเซิร์ฟเวอร์ได้ ชื่อหรือ FQDN ด้วยเหตุผลบางประการ
ฉันไม่แนะนำอย่างยิ่งที่จะใช้คำตอบนี้ การเปิดใช้งานเชลล์เอาต์เป็นความคิดที่แย่มากใน SQL Server ที่ใช้งานจริง
คุณสามารถรับ [hostname] \ [instancename] ได้โดย:
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
เซิร์ฟเวอร์อาจมีที่อยู่ 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 address ผ่าน t-sql จะอยู่ในสองค่ายนี้:
เรียกใช้ipconfig.exe
ผ่านxp_cmdshell
และแยกเอาท์พุท
สอบถาม 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;
บางครั้งคำค้นหาข้างต้นไม่ได้ผล Query # 1 จะคืนค่า NULL หากคุณเชื่อมต่อผ่านหน่วยความจำที่ใช้ร่วมกัน (ล็อกอินและรัน SSMS บนโฮสต์ SQL) แบบสอบถาม # 2 อาจไม่ส่งคืนอะไรเลยหากไม่มีการเชื่อมต่อโดยใช้โปรโตคอลหน่วยความจำที่ไม่ใช้ร่วมกัน สถานการณ์นี้น่าจะเกิดขึ้นเมื่อเชื่อมต่อกับอินสแตนซ์ SQL ที่ติดตั้งใหม่ การแก้ไขปัญหา? บังคับให้เชื่อมต่อผ่าน TCP / IP ในการดำเนินการนี้ให้สร้างการเชื่อมต่อใหม่ใน SSMS และใช้คำนำหน้า "tcp:" กับชื่อเซิร์ฟเวอร์ จากนั้นเรียกใช้แบบสอบถามอีกครั้งและคุณจะได้รับที่อยู่ IP
ในตัวแปร@@ SERVERNAME
SELECT @@SERVERNAME;
- ลองใช้สคริปต์นี้ตามความต้องการของฉัน ฟอร์แมตใหม่เพื่ออ่าน
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;
คุณสามารถใช้แบบสอบถามบรรทัดคำสั่งและดำเนินการใน mssql:
exec xp_cmdshell 'ipconfig'
xp_cmdshell
เปิดใช้งานในการกำหนดค่าความปลอดภัยของเซิร์ฟเวอร์
select @@servername
วิธีที่ง่ายกว่าในการรับชื่อเครื่องโดยไม่มี \ InstanceName คือ:
SELECT SERVERPROPERTY('MachineName')
ฉันรู้ว่านี่เป็นโพสต์เก่า แต่บางทีโซลูชันนี้อาจมีประโยชน์เมื่อคุณต้องการดึงที่อยู่ 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
เปิดใช้งาน