ChatGPT解决这个技术问题 Extra ChatGPT

如何查看活动的 SQL Server 连接?

我正在使用 SQL Server 2008 企业版。我想查看任何活动的 SQL Server 连接,以及所有连接的相关信息,例如来自哪个 IP 地址、连接到哪个数据库等。

是否有现有的命令来解决这个问题?

sys.dm_exec_sessions,要检查的会话 ID >50

P
Peter Mortensen

您可以使用 sp_who 存储过程。

提供有关 Microsoft SQL Server 数据库引擎实例中的当前用户、会话和进程的信息。可以过滤信息以仅返回那些非空闲、属于特定用户或属于特定会话的进程。


当您必须过滤特定数据库时,从 sys.sysprocesses 中选择会更好
如何仅为特定数据库添加过滤器? WHERE dbname = '数据库名称' ??我试过这个,我得到了一个错误
@Geo.Dude,Iman Abidi 的意思是从 sys.sysprocesses 制作您自己的选择查询,并向该查询添加 where 子句。您必须过滤 dbid。您可以在 sys.databases 中找到数据库 ID(或者您可以加入这两个)。
M
Martin Brown
SELECT 
    DB_NAME(dbid) as DBName, 
    COUNT(dbid) as NumberOfConnections,
    loginame as LoginName
FROM
    sys.sysprocesses
WHERE 
    dbid > 0
GROUP BY 
    dbid, loginame
;

另请参阅 sys.sysprocesses 的 Microsoft 文档。


在使事情自动化时,此查询可能比 sp_who 更有用,后者更倾向于显示。
这是我的首选方法,但它并不能完全回答 OP 的问题。建议将 hostname 添加到 SELECTGROUP BY 子句以查看连接了哪些客户端。此外,我刚刚意识到 loginame 的 Msft 错字 - 这是列名限制为 8 个字符时的产物吗?哈哈
sys.sysprocesses is deprecated 在较新版本的 SQL Server 中。它映射到这些 three management views:sys.dm_exec_connections、sys.dm_exec_sessions 和 sys.dm_exec_requests。
我喜欢ORDER BY 1, 2 DESC, 3
P
Peter Mortensen

除了 sp_who,您还可以使用“未记录的”sp_who2 系统存储过程,它可以为您提供更详细的信息。请参阅 Difference between sp_who and sp_who2


谁连接到 dbo.First?
P
Pang

单击工具栏中的“活动监视器”图标。

来自Thorstencomment

在 SQL Server Management Studio 中,右键单击服务器,从上下文菜单中选择“活动监视器” - 或 - 使用键盘快捷键 Ctrl + Alt + A。

参考:Microsoft Docs - Open Activity Monitor in SQL Server Management Studio (SSMS)


在 SQL Server Management Studio 中,右键单击服务器,从上下文菜单中选择“活动监视器” - 或 - 使用键盘快捷键 Ctrl+Alt+A
不错的选择,但它需要比从 sys.sysprocesses 提取 DB_NAME(dbid) 更多的权限。
M
Marcello Miorelli

下面是我的脚本,用于查找连接到数据库的所有会话,您可以检查这些会话是否正在执行任何 I/O,并且可以选择终止它们。

该脚本还显示每个会话的状态。

看看下面。

--==============================================================================
-- See who is connected to the database.
-- Analyse what each spid is doing, reads and writes.
-- If safe you can copy and paste the killcommand - last column.
-- Marcelo Miorelli
-- 18-july-2017 - London (UK)
-- Tested on SQL Server 2016.
--==============================================================================
USE master
go
SELECT
     sdes.session_id
    ,sdes.login_time
    ,sdes.last_request_start_time
    ,sdes.last_request_end_time
    ,sdes.is_user_process
    ,sdes.host_name
    ,sdes.program_name
    ,sdes.login_name
    ,sdes.status

    ,sdec.num_reads
    ,sdec.num_writes
    ,sdec.last_read
    ,sdec.last_write
    ,sdes.reads
    ,sdes.logical_reads
    ,sdes.writes

    ,sdest.DatabaseName
    ,sdest.ObjName
    ,sdes.client_interface_name
    ,sdes.nt_domain
    ,sdes.nt_user_name
    ,sdec.client_net_address
    ,sdec.local_net_address
    ,sdest.Query
    ,KillCommand  = 'Kill '+ CAST(sdes.session_id  AS VARCHAR)
FROM sys.dm_exec_sessions AS sdes

INNER JOIN sys.dm_exec_connections AS sdec
        ON sdec.session_id = sdes.session_id

CROSS APPLY (

    SELECT DB_NAME(dbid) AS DatabaseName
        ,OBJECT_NAME(objectid) AS ObjName
        ,COALESCE((
            SELECT TEXT AS [processing-instruction(definition)]
            FROM sys.dm_exec_sql_text(sdec.most_recent_sql_handle)
            FOR XML PATH('')
                ,TYPE
            ), '') AS Query

    FROM sys.dm_exec_sql_text(sdec.most_recent_sql_handle)

) sdest
WHERE sdes.session_id <> @@SPID
  AND sdest.DatabaseName ='yourdatabasename'
--ORDER BY sdes.last_request_start_time DESC

--==============================================================================

2022 年 1 月 20 日更新

我现在有一个更好的版本,它使用 sys.dm_tran_locks 这在您需要所有用户离开特定数据库时特别有用,这就是为什么我有这个参数 @dbname

即使有人只是打开 SSMS 并连接到数据库,它也会显示在此查询中。

DECLARE @dbname SYSNAME =NULL

SELECT 
        sdes.session_id 
       ,sdes.login_time 
       ,sdes.last_request_start_time
       ,sdes.last_request_end_time
       ,sdes.is_user_process
       ,sdes.host_name
       ,sdes.program_name
       ,sdes.login_name
       ,sdes.status

       ,sdec.num_reads
       ,sdec.num_writes
       ,sdec.last_read
       ,sdec.last_write
       ,sdes.reads
       ,sdes.logical_reads
       ,sdes.writes
       
       ,DatabaseName = COALESCE( db_name(sdes.database_id),  N'')
       ,sdest.ObjName
    ,sdes.client_interface_name
    ,sdes.nt_domain
    ,sdes.nt_user_name
    ,sdec.client_net_address
    ,sdec.local_net_address
    ,sdest.Query
    ,KillCommand  = 'Kill '+ CAST(sdes.session_id  AS VARCHAR)

from sys.dm_tran_locks t
INNER JOIN sys.dm_exec_sessions sdes
        ON T.request_session_id = sdes.session_id

LEFT OUTER JOIN sys.dm_exec_connections AS sdec 
        ON sdec.session_id = sdes.session_id

OUTER APPLY (

                SELECT DB_NAME(dbid) AS DatabaseName
                    ,OBJECT_NAME(objectid) AS ObjName
                    ,COALESCE((
                            SELECT TEXT AS [processing-instruction(definition)]
                            FROM sys.dm_exec_sql_text(sdec.most_recent_sql_handle) 
                            FOR XML PATH('')
                                ,TYPE
                            ), '') AS Query

                FROM sys.dm_exec_sql_text(sdec.most_recent_sql_handle)

    ) sdest
where t.resource_type = 'database' 
  and t.resource_database_id = CASE WHEN @dbname IS NULL 
                                    THEN t.resource_database_id  
                                    ELSE DB_ID(@dbname)  
                               END 
  and t.request_type = 'LOCK' 
  and t.request_status = 'GRANT'

这很棒。实际上向我显示了查询!
@JacobIRR 是的,但是,现在我将它与这个混合使用:select request_session_id from sys.dm_tran_locks where resource_type = 'database' and resource_database_id = 3 and request_type = 'LOCK' and request_status = 'GRANT';
我会更新答案,因为它真的帮了我很多
D
Don Rolling

我把它放在一起,以便您可以对结果进行一些查询

Declare @dbName varchar(150)
set @dbName = '[YOURDATABASENAME]'

--Total machine connections
--SELECT  COUNT(dbid) as TotalConnections FROM sys.sysprocesses WHERE dbid > 0

--Available connections
DECLARE @SPWHO1 TABLE (DBName VARCHAR(1000) NULL, NoOfAvailableConnections VARCHAR(1000) NULL, LoginName VARCHAR(1000) NULL)
INSERT INTO @SPWHO1 
    SELECT db_name(dbid), count(dbid), loginame FROM sys.sysprocesses WHERE dbid > 0 GROUP BY dbid, loginame
SELECT * FROM @SPWHO1 WHERE DBName = @dbName

--Running connections
DECLARE @SPWHO2 TABLE (SPID VARCHAR(1000), [Status] VARCHAR(1000) NULL, [Login] VARCHAR(1000) NULL, HostName VARCHAR(1000) NULL, BlkBy VARCHAR(1000) NULL, DBName VARCHAR(1000) NULL, Command VARCHAR(1000) NULL, CPUTime VARCHAR(1000) NULL, DiskIO VARCHAR(1000) NULL, LastBatch VARCHAR(1000) NULL, ProgramName VARCHAR(1000) NULL, SPID2 VARCHAR(1000) NULL, Request VARCHAR(1000) NULL)
INSERT INTO @SPWHO2 
    EXEC sp_who2 'Active'
SELECT * FROM @SPWHO2 WHERE DBName = @dbName

P
Pang

MS 的查询解释了 KILL 命令的使用,它提供了连接信息,非常有用:

SELECT conn.session_id, host_name, program_name,
    nt_domain, login_name, connect_time, last_request_end_time 
FROM sys.dm_exec_sessions AS sess
JOIN sys.dm_exec_connections AS conn
   ON sess.session_id = conn.session_id;

s
sinkmanu

您可以执行以下 T-SQL 命令:

SELECT * FROM sys.dm_exec_sessions WHERE status = 'running';