我正在研究多租户解决方案。因此,我们的 SQL Server 上有很多数据库。我正在查看一个锁定问题,并且需要能够查看正在等待哪些锁。
我查询了sys.dm_tran_locks动态视图,但还想包括 resource_associated_entity_id 列引用的数据库、对象和索引名称。这链接到sys.partitions表,但该表仅返回当前数据库的行,而我正在查看的锁分布在多个数据库中。
有没有办法在不创建游标和使用动态生成的查询的情况下获取这些信息?
我正在研究多租户解决方案。因此,我们的 SQL Server 上有很多数据库。我正在查看一个锁定问题,并且需要能够查看正在等待哪些锁。
我查询了sys.dm_tran_locks动态视图,但还想包括 resource_associated_entity_id 列引用的数据库、对象和索引名称。这链接到sys.partitions表,但该表仅返回当前数据库的行,而我正在查看的锁分布在多个数据库中。
有没有办法在不创建游标和使用动态生成的查询的情况下获取这些信息?
简短的回答:不,没有办法避免这种情况。sys.partitions
和其他特定于数据库的视图那样烦人。对于整个对象,您通常可以使用 来解决这个问题OBJECT_NAME()
,因为它需要一个数据库 ID。对于分配 ID,您不走运。
从技术上讲,您可以避免使用我们的老朋友自己编写游标sp_msforeachdb
,但由于没有记录,并且通常不会以您想要的格式给出结果,所以自己编写是一个更好的主意。
因为sys.dm_tran_locks
是高度动态的,所以在需要的时候获取锁定信息并不容易。一种可能的替代方法是使用分析器跟踪或扩展事件会话来获取获取的锁的确切顺序(显然,由于这是大量数据,您只会在对特定查询进行故障排除时这样做)。如果你只需要知道当众所周知的狗屎击中粉丝时谁在阻止事情,那么sp_msforeachdb 'dbcc opentran(''?'')'
它仍然非常有效。
从技术上讲“不”。没有元数据函数可以获取当前数据库上下文之外的索引名称。当尝试以类似有用的方式使用它们时,这个可悲的事实也会对使用以下内容产生不利影响:
所以你有两个选择:
database_id
,并通过“context connection = true”连接以查询预期的系统视图(这就是我在SQL#中的索引名称和 sys.objects 方面解决此问题的方法,但是将database_id
SQLCLR 函数(标量或 TVF)作为参数接收并使其通过动态构建的 SQL 在本地连接到所述数据库的技术对于任何其他元数据都适用)。SqlCommand.CommandText
并使用 ID 作为SqlParameter
s。因此,就获取索引名称而言,签名将是:GetIndexName(@DatabaseName sysname, @object_id INT, @index_id INT)
GetIndexName(DB_NAME(dmv.database_id), dmv.object_id, dmv.index_id)
仅供参考,这里是元数据函数列表,按您是否可以指定数据库或仅当前数据库分组:
可以指定数据库
database_id
参数)database_id
参数)仅当前数据库