sys.dm_exec_requests中statement_start_offset与statement_end_offset

1.缘起

mssql中查早阻塞与及其相关联的sql时,遇到如下内容,故记录一下,

substring(dest_blocked.text,der.statement_start_offset/2+1,(case when der.statement_end_offset=-1 then  DATALENGTH(der.statement_end_offset)
	 else der.statement_end_offset end-der.statement_start_offset)/2+1) as blocked_statement

2.根因

statement_start_offset与statement_end_offset主要用于定位sql的起始与结束位置,但是为何要/2+1,从网路上查询得知:

It's because data returned from sys.dm_exec_sql_text function is in Unicode. 
1 character takes 2 bytes. The SUBSTRING works on character data types (not on bytes). 
So we need to divide the number of bytes by 2 + 1 to have location of the first character in SQL Query that is inside text.

主要是因为sys.dm_exec_sql_text返回的offset是unicode,也就是说返回的是bytes数,1个字符要占用2个bytes,而substring使用character为单位取值,故需要除以2

3.示例

看一下示例:
主要用于返回substring取值的sql与不使用substring取值的完整sql
substring取值的sql

select 'a' as A_query,der.session_id,der.statement_start_offset,der.statement_end_offset, substring(dest.text,der.statement_start_offset/2+1,(case when der.statement_end_offset= -1 then datalength(dest.text)
else der.statement_end_offset end - der.statement_start_offset)/2+1) as statement from sys.dm_exec_requests der
cross apply sys.dm_exec_sql_text(der.sql_handle) dest
union
select 'b' as b_query,der.session_id,der.statement_start_offset,der.statement_end_offset, dest.text as statement from sys.dm_exec_requests der
cross apply sys.dm_exec_sql_text(der.sql_handle) dest
order by session_id

返回如下:
在这里插入图片描述
注意上图中的A_query字段:
a 代表使用substring取值的sql
b 代表不使用substring取值的完整sql

如下,是返回的完整sql:
substring取值的sql(sql_1)

EXECUTE [cmCriticalManufacturingODSLink]..[dbo].sp_executesql @sqlcommand, N'@sqlrowcnt int OUTPUT', @sqlrowcnt=@sqlrowcnt output

不使用substring取值的完整sql(sql_2)

(@sqlcommand nvarchar(max),@sqlrowcnt As int OUTPUT)EXECUTE [cmCriticalManufacturingODSLink]..[dbo].sp_executesql @sqlcommand, N'@sqlrowcnt int OUTPUT', @sqlrowcnt=@sqlrowcnt output

由于statement_start_offset返回是104个bytes,换算成字符就是52个字符
比对上面sql_1与sql_2,可以看到sql_1刚好从第53个字符开始截取,这也就是要+1的原因

4.附录

标题1中的完整sql:

select dtl.resource_type,
case when dtl.resource_type in ('database','file','metadata') then resource_type
     when dtl.resource_type in ('object') then object_name(dtl.resource_associated_entity_id,dtl.resource_database_id) 
	 when dtl.resource_type in ('key','page','rid') then (select object_name(object_id,dtl.resource_database_id) from sys.partitions where hobt_id=dtl.resource_associated_entity_id)
	 else 'unidentifer' end as parent_object,
	 dtl.request_mode,
	 dtl.request_status,
	 dowt.wait_duration_ms,
	 dowt.wait_type,
	 dowt.session_id as blocked_session_id,
	 des_blocked.login_name as blocked_user,
	 substring(dest_blocked.text,der.statement_start_offset/2+1,(case when der.statement_end_offset=-1 then  DATALENGTH(der.statement_end_offset)
	 else der.statement_end_offset end-der.statement_start_offset)/2+1) as blocked_statement,
	 dowt.blocking_session_id,
	 der.blocking_session_id,
	 des_blocking.login_name,
	 dest_blocking.text,
	 dowt.resource_description
	 from sys.dm_tran_locks dtl 
join sys.dm_os_waiting_tasks dowt on dtl.lock_owner_address=dowt.resource_address
join sys.dm_exec_requests der on dowt.session_id=der.session_id
join sys.dm_exec_sessions des_blocked on dowt.session_id=des_blocked.session_id
join sys.dm_exec_sessions des_blocking on dowt.blocking_session_id=des_blocking.session_id
join sys.dm_exec_connections dec on des_blocking.session_id=dec.most_recent_session_id
cross apply sys.dm_exec_sql_text( dec.most_recent_sql_handle) dest_blocking
cross apply sys.dm_exec_sql_text( der.sql_handle) as dest_blocked
where dtl.resource_database_id=db_id() and dtl.resource_type not in ('database','file') 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sys.dm_exec_requests表包括以下字段: 1. session_id:正在执行请求的会话的ID。 2. request_id:请求的唯一标识符。 3. start_time:请求开始执行的时间。 4. status:请求的当前状态。 5. command:请求的类型。 6. sql_handle:请求所使用的SQL语句的句柄。 7. statement_start_offset:请求使用的SQL语句的起始偏移量。 8. statement_end_offset:请求使用的SQL语句的结束偏移量。 9. plan_handle:请求所使用的计划的句柄。 10. database_id:请求所在的数据库的ID。 11. user_id:请求所属的用户的ID。 12. wait_type:请求正在等待的类型。 13. wait_time:请求已经等待的时间。 14. last_wait_type:请求最后等待的类型。 15. cpu_time:请求已使用的CPU时间。 16. total_elapsed_time:请求已等待的总时间。 17. reads:请求已读取的页数。 18. writes:请求已写入的页数。 19. logical_reads:请求已读取的逻辑页数。 20. text_size:请求使用的SQL语句的文本大小。 21. language:请求使用的语言。 22. date_format:请求使用的日期格式。 23. date_first:请求使用的第一个日期。 24. quoted_identifier:请求使用的引号标识符。 25. arithabort:请求使用的算术终止标志。 26. ansi_null_dflt_on:请求使用的ANSI_NULL_DFLT_ON标志。 27. ansi_defaults:请求使用的ANSI_DEFAULTS标志。 28. ansi_warnings:请求使用的ANSI_WARNINGS标志。 29. ansi_padding:请求使用的ANSI_PADDING标志。 30. ansi_nulls:请求使用的ANSI_NULLS标志。 31. concat_null_yields_null:请求使用的CONCAT_NULL_YIELDS_NULL标志。 32. transaction_isolation_level:请求使用的事务隔离级别。 33. lock_timeout:请求使用的锁超时时间。 34. deadlock_priority:请求使用的死锁优先级。 35. row_count:请求所影响的行数。 36. prev_error:请求上一个错误的状态。 注释:以上信息来自于Microsoft SQL Server官网,仅供参考。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值