我没有像下面的问题那样引用过滤sp_who2
SQL Server: Filter output of sp_who2而是关于使用@loginame
参数仅为特定用户获取结果。
例如:
EXEC sp_who @loginame = 'sa'
EXEC sp_who2 @loginame = 'sa'
使用sp_who
参数运行@loginame
时,结果仅会过滤给特定用户,但该行为不在sp_who2
中。
答案 0 :(得分:3)
基于此处的连接项目
在这里
我将建议您使用未记录的功能“由您自行承担风险”,因为结果无法保证,可能会或可能不会在将来的版本中使用 没有太多警告。 此外,可能存在与未解决的代码相关的错误。最后,正如您所提到的,我曾经知道使用sp_who2
的唯一过滤器是过滤“活动”连接。这就是我使用DMV检查活动连接的原因。
如果无法将存储过程部署到您的环境,则还可以运行以下代码。应该注意的是,它是非常重量级的并且将产生“倍数”会话,因为它拉动与每个会话id相关联的子任务(执行上下文)。另外,如果你有一个执行上下文命中tempdb和用户db,它会进一步复制它。
SELECT
instance_name = @@SERVERNAME,
GETDATE() AS collection_date,
s.session_id,
r.request_id,
DB_NAME(r.database_id) as request_database_name,
r.command,
w.exec_context_id,
w.blocking_session_id,
w.blocking_exec_context_id,
s.login_time,
s.host_name,
s.program_name,
s.client_interface_name,
s.login_name,
s.cpu_time AS session_cpu_time,
r.cpu_time AS request_cpu_time ,
s.memory_usage,
s.total_scheduled_time,
s.total_elapsed_time,
s.last_request_start_time,
s.last_request_end_time,
request_start_time = r.start_time,
s.reads as session_reads,
r.reads AS request_reads,
s.logical_reads AS session_logical_reads ,
r.logical_reads as request_logical_reads ,
s.writes as session_writes,
r.writes AS request_writes ,
r.wait_type AS request_wait_type ,
r.wait_time AS request_wait_time ,
w.wait_type AS waiting_tasks_wait_type ,
w.wait_duration_ms AS waiting_tasks_wait_duration,
SUBSTRING(qt.text,r.statement_start_offset/2,
(case when r.statement_end_offset = -1
then len(convert(nvarchar(max), qt.text)) * 2
else r.statement_end_offset end -r.statement_start_offset)/2) as request_query_text,
CAST(qp.query_plan as XML) AS query_plan,
r.sql_handle AS request_sql_handle ,
r.plan_handle AS request_plan_handle,
w.resource_description,
t.transaction_id,
t.name,
t.transaction_begin_time,
t.transaction_type,
t.transaction_state,
t.database_transaction_log_record_count,
t.database_transaction_log_bytes_used,
t.database_transaction_log_bytes_reserved,
t.database_id,
t.database_transaction_state,
t.enlist_count,
t.is_user_transaction,
t.transaction_descriptor,
(SELECT
lock.resource_type AS resource_type,
lock.resource_subtype AS resource_subtype,
LTRIM(RTRIM(lock.resource_description)) AS resource_description,
lock.resource_database_id AS resource_database_id,
lock.resource_associated_entity_id AS resource_database_entity_id,
lock.resource_lock_partition AS resource_lock_partition,
lock.request_mode AS request_mode,
lock.request_type AS request_type,
lock.request_status AS request_status,
lock.request_exec_context_id as request_context_id,
DB_NAME(lock.resource_database_id) AS resource_database_name
FROM sys.dm_tran_locks lock
WHERE lock.request_session_id = r.session_id
AND lock.request_exec_context_id = w.exec_context_id
FOR XML AUTO, TYPE, ROOT('locks'))
AS locks,
tu.user_objects_alloc_page_count,
tu.user_objects_dealloc_page_count,
tu.internal_objects_alloc_page_count,
tu.internal_objects_dealloc_page_count
FROM sys.dm_exec_sessions s
JOIN sys.dm_exec_requests r
ON s.session_id = r.session_id
LEFT JOIN sys.dm_os_waiting_tasks w
ON s.session_id = w.session_id
LEFT JOIN (
SELECT
DISTINCT
at.transaction_id,
at.name,
at.transaction_begin_time,
at.transaction_type,
at.transaction_state,
dt.database_transaction_log_record_count,
dt.database_transaction_log_bytes_used,
dt.database_transaction_log_bytes_reserved,
dt.database_id,
dt.database_transaction_state,
st.enlist_count,
st.is_user_transaction,
st.transaction_descriptor
FROM sys.dm_tran_active_transactions at
JOIN sys.dm_tran_database_transactions dt
ON at.transaction_id = dt.transaction_id
LEFT JOIN sys.dm_tran_session_transactions st
ON st.transaction_id = at.transaction_id
) t
ON t.transaction_id = r.transaction_id
LEFT JOIN sys.dm_db_task_space_usage tu
ON tu.exec_context_id = w.exec_context_id
AND tu.session_id = s.session_id
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) as qt
OUTER APPLY sys.dm_exec_query_plan(r.plan_handle) AS qp
WHERE r.session_id > 50 AND r.session_id != @@SPID
-- AND s.login_name = 'sa'
答案 1 :(得分:2)
在挖掘sp_who2
代码后,我发现了这个错误。所以解释很简单。
有4个参数
DECLARE @sidlow VARBINARY(85)
,@sidhigh VARBINARY(85)
,@sid1 VARBINARY(85)
,@spidlow INT
,@spidhigh INT
他们默认为以下
SELECT @sidlow = CONVERT(VARBINARY(85), ( REPLICATE(CHAR(0), 85) ))
SELECT @sidhigh = CONVERT(VARBINARY(85), ( REPLICATE(CHAR(1), 85) ))
SELECT @spidlow = 0, @spidhigh = 32767
,如果您传入@loginame
参数@sidlow
,@sidhigh
会在以下声明中更新。
IF ( @sid1 IS NOT NULL ) --Parm is a recognized login name.
BEGIN
SELECT @sidlow = SUSER_SID(@loginame)
,@sidhigh = SUSER_SID(@loginame)
GOTO LABEL_17PARM1EDITED
END
但是一旦你到达SP的底部,假设它返回@sidlow
和@sidhigh
,则执行以下代码。
SELECT @charMaxLenLoginName = CONVERT(VARCHAR, ISNULL(MAX(DATALENGTH(loginname)), 5))
,@charMaxLenDBName = CONVERT(VARCHAR, ISNULL(MAX(DATALENGTH(RTRIM(CONVERT(VARCHAR(128), DB_NAME(dbid))))), 6))
,@charMaxLenCPUTime = CONVERT(VARCHAR, ISNULL(MAX(DATALENGTH(RTRIM(CONVERT(VARCHAR(128), cpu)))), 7))
,@charMaxLenDiskIO = CONVERT(VARCHAR, ISNULL(MAX(DATALENGTH(RTRIM(CONVERT(VARCHAR(128), physical_io)))), 6))
,@charMaxLenCommand = CONVERT(VARCHAR, ISNULL(MAX(DATALENGTH(RTRIM(CONVERT(VARCHAR(128), cmd)))), 7))
,@charMaxLenHostName = CONVERT(VARCHAR, ISNULL(MAX(DATALENGTH(RTRIM(CONVERT(VARCHAR(128), hostname)))), 8))
,@charMaxLenProgramName = CONVERT(VARCHAR, ISNULL(MAX(DATALENGTH(RTRIM(CONVERT(VARCHAR(128), program_name)))),
11))
,@charMaxLenLastBatch = CONVERT(VARCHAR, ISNULL(MAX(DATALENGTH(RTRIM(CONVERT(VARCHAR(128), last_batch_char)))),
9))
FROM #tb1_sysprocesses
WHERE spid >= @spidlow
AND spid <= @spidhigh
正如您所看到的那样@sidlow
和@sidhigh
正在使用@spidlow
和@spidhigh
这些从未更改的内容。因此,您仍然可以获得所有记录。
现在传递的内容是'active'
EXEC sp_who2 @loginame = 'sa'
EXEC sp_who2 @loginame = 'active'
第一个将返回前面讨论的所有行,但第二个执行只会返回活动行,因为以下代码
--------Screen out any rows?
IF ( @loginame IN ( 'active' ) )
DELETE #tb1_sysprocesses
WHERE LOWER(status) = 'sleeping'
AND UPPER(cmd) IN ( 'AWAITING COMMAND', 'LAZY WRITER', 'CHECKPOINT SLEEP' )
AND blocked = 0
此代码删除临时表#tb1_sysprocesses
中将用于返回的所有“非活动”记录。
<强>结论强>:
这个SP就像在@swasheck提供的链接中提到的那样被窃听,并且根据微软的回复,他们不会修复它。他们建议使用DMV而不是这个。
为程序提供有效的登录名不会修改结果。
EXEC sp_who2 @loginame = 'sa' --All Rows returned
向程序提供'Active'
会将结果仅过滤到“活动”记录。
EXEC sp_who2 @loginame = 'active' --Only Active SIDs returned