死锁 - 从死锁报告中查找完整的 SQL 语句
Deadlocks - Finding full SQL statement from deadlock report
我有一个针对 SQL Server 2016 数据库的应用程序 运行 导致死锁。
死锁图显示了底层对象的 Objectid 和对象名称。它还提供了截断的 SQL 语句。
但是,有些语句非常大,超出了 <inputbuf>
实体的 XML 死锁报告中看似 1024 个字符的限制。我希望能够查看这些锁中涉及的完整语句,以便重现和调试问题。
有没有办法增加这个限制,或者有没有办法在给定死锁图中包含的事务描述符的情况下找到完整的 SQL 语句?
如果您使用的是存储过程等代码对象,则可以使用第三方工具轻松找到它们。
一些在过去为我节省了大量时间的免费软件。
SSMS 的免费插件。
- ApexSQL Search.
- Redgate 的 SQL Search.
或者你可以通过这个代码找到-
-- =============================================
-- Author: Sharon
-- Create date: 12/10/2014
-- Description: FindObject
-- =============================================
ALTER PROCEDURE [dbo].[usp_FindObject]
@Text NVARCHAR(4000),
@DatabaseName sysname,
@Table BIT = 1,
@Column BIT = 1,
@View BIT = 1,
@Function BIT = 1,
@Procedure BIT = 1,
@Trigger BIT = 1,
@Constreint BIT = 1,
@Job BIT = 0,
@ReportServer BIT = 0,
@IsExactMatch BIT = 0
AS
BEGIN
SET NOCOUNT ON;
DECLARE @IsAllDatabases BIT = 0;
DECLARE @Print NVARCHAR(2048) = N'';
DECLARE @cmd NVARCHAR(MAX) = N'';
IF @Text IS NULL
RAISERROR('Insert text to look for!', 16, 1);
IF @IsExactMatch IS NULL
SET @IsExactMatch = 0;
IF IIF(@Table IS NULL, 0, @Table) + IIF(@Column IS NULL, 0, @Column) + IIF(@View IS NULL, 0, @View)
+ IIF(@Function IS NULL, 0, @Function) + IIF(@Procedure IS NULL, 0, @Procedure)
+ IIF(@Trigger IS NULL, 0, @Trigger) + IIF(@Constreint IS NULL, 0, @Constreint) > 0
BEGIN
IF NOT EXISTS ( SELECT TOP (1) 1
FROM sys.databases
WHERE name = @DatabaseName)
BEGIN
SET @IsAllDatabases = 1;
CREATE TABLE #DBResult
( [Database Name] sysname NULL,
[Object Schema] sysname NULL,
[Object Name] sysname NULL,
[Object Type] sysname NULL,
[TEXT Location] NVARCHAR(MAX) NULL,
[Position] NVARCHAR(1000)
);
DECLARE curDatabases CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
SELECT d.name
FROM master.sys.databases d
WHERE d.state = 0 --ONLINE
AND d.database_id > 4
AND HAS_DBACCESS(d.name) = 1 -- Have access
AND DATABASEPROPERTYEX(d.name, 'Updateability') = 'READ_WRITE'
AND NOT EXISTS
(
SELECT TOP (1) 1
FROM sys.dm_hadr_database_replica_states AS drs
INNER JOIN sys.availability_replicas AS ar ON ar.replica_id = drs.replica_id
INNER JOIN sys.dm_hadr_availability_group_states ags ON ags.group_id = ar.group_id
WHERE drs.database_id = d.database_id
AND ar.secondary_role_allow_connections = 0
AND ags.primary_replica <> CONVERT(sysname, SERVERPROPERTY('ServerName'))
);
END;
ELSE
BEGIN
DECLARE curDatabases CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
SELECT d.name
FROM master.sys.databases d
WHERE d.state = 0 --ONLINE
AND d.database_id > 4
AND HAS_DBACCESS(d.name) = 1 -- Have access
AND DATABASEPROPERTYEX(d.name, 'Updateability') = 'READ_WRITE'
AND NOT EXISTS
(
SELECT TOP (1) 1
FROM sys.dm_hadr_database_replica_states AS drs
INNER JOIN sys.availability_replicas AS ar ON ar.replica_id = drs.replica_id
INNER JOIN sys.dm_hadr_availability_group_states ags ON ags.group_id = ar.group_id
WHERE drs.database_id = d.database_id
AND ar.secondary_role_allow_connections = 0
AND ags.primary_replica <> CONVERT(sysname, SERVERPROPERTY('ServerName'))
)
AND d.name = @DatabaseName;
CREATE TABLE #Result
(
[Object Schema] sysname NULL,
[Object Name] sysname NULL,
[Object Type] sysname NULL,
[TEXT Location] NVARCHAR(MAX) NULL,
[Position] NVARCHAR(1000)
);
END
-- Table names
IF @Table = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(IIF(@DatabaseName IS NOT NULL,N'USE [' + @DatabaseName + '];',N''),N'
INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'TABLE_SCHEMA AS [Object Schema]
,TABLE_NAME AS [Object Name]
,TABLE_TYPE AS [Object Type]
,''Table Name'' AS [TEXT Location]
,NULL
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = N''BASE TABLE''
AND TABLE_NAME LIKE ''%''+@Text+''%''');
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search Table on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
--Column names| computed_columns
IF @Column = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(IIF(@DatabaseName IS NOT NULL,N'USE [' + @DatabaseName + '];',N''),N'
INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'TABLE_SCHEMA AS [Object Schema]
,TABLE_NAME AS [Object Name]
,''COLUMN'' AS [Object Type]
,COLUMN_NAME AS [TEXT Location]
,NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE ''%''+@Text+''%''
UNION ALL
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,o.type_desc AS [Object Type]
,C.definition AS [TEXT Location]
,NULL
FROM sys.computed_columns C
INNER JOIN sys.objects o ON C.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE C.definition Like ''%''+@Text+''%''
') ;
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search Column on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
--PROCEDURE
IF @Procedure = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(
N'INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,''PROCEDURE'' AS [Object Type]
,m.definition AS [TEXT Location]
,SUBSTRING(m.definition,PATINDEX(''%''+@Text+''%'',m.definition),100)
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id=o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE m.definition Like ''%''+@Text+''%''
and o.type = ''P''');
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search Procedure on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
-- FUNCTION
IF @Function = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(
N'INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,''FUNCTION('' + o.type + '')'' COLLATE SQL_Latin1_General_CP1_CI_AS AS [Object Type]
,m.definition AS [TEXT Location]
,SUBSTRING(m.definition,PATINDEX(''%''+@Text+''%'',m.definition),100)
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE m.definition Like ''%''+@Text+''%''
and o.type in (''FN'',''AF'',''FS'',''FT'',''IF'',''TF'')');
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search Function on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
-- Trigger
IF @Trigger = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(
N'INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,''FUNCTION('' + o.type + '')'' COLLATE SQL_Latin1_General_CP1_CI_AS AS [Object Type]
,m.definition AS [TEXT Location]
,SUBSTRING(m.definition,PATINDEX(''%''+@Text+''%'',m.definition),100)
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE m.definition Like ''%''+@Text+''%''
and o.type = ''TR''');
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search Trigger on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
--View
IF @View = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(
N'INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,o.type_desc COLLATE SQL_Latin1_General_CP1_CI_AS AS [Object Type]
,m.definition AS [TEXT Location]
,SUBSTRING(m.definition,PATINDEX(''%''+@Text+''%'',m.definition),100)
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE m.definition Like ''%''+@Text+''%''
and o.type = ''v''');
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search View on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
--default_constraints| check_constraints
IF @Constreint = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(
N'INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,o.type_desc AS [Object Type]
,D.definition AS [TEXT Location]
,SUBSTRING(D.definition,PATINDEX(''%''+@Text+''%'',D.definition),100)
FROM sys.default_constraints D
INNER JOIN sys.objects o ON D.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE D.definition Like ''%''+@Text+''%''
UNION ALL
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,o.type_desc AS [Object Type]
,C.definition AS [TEXT Location]
,SUBSTRING(D.definition,PATINDEX(''%''+@Text+''%'',C.definition),100)
FROM sys.check_constraints C
INNER JOIN sys.objects o ON C.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE C.definition Like ''%''+@Text+''%''');
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search Constreint on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
IF OBJECT_ID('tempdb..#DBResult') IS NOT NULL
BEGIN
SELECT *
FROM #DBResult
WHERE @IsExactMatch = 0
OR (@IsExactMatch = 1 AND [Object Name] = @Text);
DROP TABLE #DBResult;
END
IF OBJECT_ID('tempdb..#Result') IS NOT NULL
BEGIN
SELECT *
FROM #Result
WHERE @IsExactMatch = 0
OR (@IsExactMatch = 1 AND [Object Name] = @Text);
DROP TABLE #Result;
END
END;
END;
-- Job
IF @Job = 1
BEGIN
DECLARE @PreviewTextSize INT = 100;
SELECT 'Job Steps' AS SearchType,
j.[name] AS [Job Name],
s.step_id AS [Step #],
REPLACE(
REPLACE(
SUBSTRING(s.command, CHARINDEX(@Text, s.command) - @PreviewTextSize / 2, @PreviewTextSize),
CHAR(13) + CHAR(10),
''),
@Text,
'***' + @Text + '***') AS Command
FROM msdb.dbo.sysjobs j
INNER JOIN msdb.dbo.sysjobsteps s ON j.job_id = s.job_id
WHERE s.command LIKE '%' + @Text + '%';
END;
-- SSRS
IF @ReportServer = 1
BEGIN
IF EXISTS (SELECT TOP (1) 1 FROM sys.databases WHERE name = 'ReportServer')
BEGIN;
WITH cte AS
(
--gets the RDL; note the double convert.
SELECT [Path],
[Name] AS Report_Name,
CONVERT(XML, CONVERT(VARBINARY(MAX), Content)) AS rdl
FROM ReportServer.dbo.Catalog)
SELECT LEFT([Path], LEN([Path]) - CHARINDEX('/', REVERSE([Path])) + 1) AS Report_Path,
Report_Name,
T1.N.value('@Name', 'nvarchar(128)') AS DataSetName,
T2.N.value('(*:DataSourceName/text())[1]', 'nvarchar(128)') AS DataSourceName,
ISNULL(T2.N.value('(*:CommandType/text())[1]', 'nvarchar(128)'), 'T-SQL') AS CommandType,
T2.N.value('(*:CommandText/text())[1]', 'nvarchar(max)') AS CommandText
INTO #SSRS
FROM cte AS T
CROSS APPLY T.rdl.nodes('/*:Report/*:DataSets/*:DataSet') AS T1(N)
CROSS APPLY T1.N.nodes('*:Query') AS T2(N)
ORDER BY Report_Path,
Report_Name,
DataSetName,
DataSourceName,
CommandType,
CommandText;
SELECT *
FROM #SSRS
WHERE CommandText LIKE '%' + @Text + '%';
END;
DEALLOCATE curDatabases;
END;
但是,如果您与 EF o Nhibernate 一起工作,您将处于困境
我发现我可以使用 SQL 句柄字符串获取死锁中每个查询的完整 SQL 文本(SQL 句柄包含在死锁图中/XDL ).
例如,死锁内 XML:
<frame procname="adhoc" line="1" stmtend="368" sqlhandle="0x02000000309a63065dbc0db09405222fe0f66eb954ed1d870000000000000000000000000000000000000000">
将 sqlhandle 传递给 sys.dm_exec_sql_text
SELECT * FROM sys.dm_exec_sql_text(0x02000000309a63065dbc0db09405222fe0f66eb954ed1d870000000000000000000000000000000000000000000000000000000000000000000000000) -- modify this value with your actual sql_handle
我有一个针对 SQL Server 2016 数据库的应用程序 运行 导致死锁。
死锁图显示了底层对象的 Objectid 和对象名称。它还提供了截断的 SQL 语句。
但是,有些语句非常大,超出了 <inputbuf>
实体的 XML 死锁报告中看似 1024 个字符的限制。我希望能够查看这些锁中涉及的完整语句,以便重现和调试问题。
有没有办法增加这个限制,或者有没有办法在给定死锁图中包含的事务描述符的情况下找到完整的 SQL 语句?
如果您使用的是存储过程等代码对象,则可以使用第三方工具轻松找到它们。 一些在过去为我节省了大量时间的免费软件。 SSMS 的免费插件。
- ApexSQL Search.
- Redgate 的 SQL Search.
或者你可以通过这个代码找到-
-- =============================================
-- Author: Sharon
-- Create date: 12/10/2014
-- Description: FindObject
-- =============================================
ALTER PROCEDURE [dbo].[usp_FindObject]
@Text NVARCHAR(4000),
@DatabaseName sysname,
@Table BIT = 1,
@Column BIT = 1,
@View BIT = 1,
@Function BIT = 1,
@Procedure BIT = 1,
@Trigger BIT = 1,
@Constreint BIT = 1,
@Job BIT = 0,
@ReportServer BIT = 0,
@IsExactMatch BIT = 0
AS
BEGIN
SET NOCOUNT ON;
DECLARE @IsAllDatabases BIT = 0;
DECLARE @Print NVARCHAR(2048) = N'';
DECLARE @cmd NVARCHAR(MAX) = N'';
IF @Text IS NULL
RAISERROR('Insert text to look for!', 16, 1);
IF @IsExactMatch IS NULL
SET @IsExactMatch = 0;
IF IIF(@Table IS NULL, 0, @Table) + IIF(@Column IS NULL, 0, @Column) + IIF(@View IS NULL, 0, @View)
+ IIF(@Function IS NULL, 0, @Function) + IIF(@Procedure IS NULL, 0, @Procedure)
+ IIF(@Trigger IS NULL, 0, @Trigger) + IIF(@Constreint IS NULL, 0, @Constreint) > 0
BEGIN
IF NOT EXISTS ( SELECT TOP (1) 1
FROM sys.databases
WHERE name = @DatabaseName)
BEGIN
SET @IsAllDatabases = 1;
CREATE TABLE #DBResult
( [Database Name] sysname NULL,
[Object Schema] sysname NULL,
[Object Name] sysname NULL,
[Object Type] sysname NULL,
[TEXT Location] NVARCHAR(MAX) NULL,
[Position] NVARCHAR(1000)
);
DECLARE curDatabases CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
SELECT d.name
FROM master.sys.databases d
WHERE d.state = 0 --ONLINE
AND d.database_id > 4
AND HAS_DBACCESS(d.name) = 1 -- Have access
AND DATABASEPROPERTYEX(d.name, 'Updateability') = 'READ_WRITE'
AND NOT EXISTS
(
SELECT TOP (1) 1
FROM sys.dm_hadr_database_replica_states AS drs
INNER JOIN sys.availability_replicas AS ar ON ar.replica_id = drs.replica_id
INNER JOIN sys.dm_hadr_availability_group_states ags ON ags.group_id = ar.group_id
WHERE drs.database_id = d.database_id
AND ar.secondary_role_allow_connections = 0
AND ags.primary_replica <> CONVERT(sysname, SERVERPROPERTY('ServerName'))
);
END;
ELSE
BEGIN
DECLARE curDatabases CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
SELECT d.name
FROM master.sys.databases d
WHERE d.state = 0 --ONLINE
AND d.database_id > 4
AND HAS_DBACCESS(d.name) = 1 -- Have access
AND DATABASEPROPERTYEX(d.name, 'Updateability') = 'READ_WRITE'
AND NOT EXISTS
(
SELECT TOP (1) 1
FROM sys.dm_hadr_database_replica_states AS drs
INNER JOIN sys.availability_replicas AS ar ON ar.replica_id = drs.replica_id
INNER JOIN sys.dm_hadr_availability_group_states ags ON ags.group_id = ar.group_id
WHERE drs.database_id = d.database_id
AND ar.secondary_role_allow_connections = 0
AND ags.primary_replica <> CONVERT(sysname, SERVERPROPERTY('ServerName'))
)
AND d.name = @DatabaseName;
CREATE TABLE #Result
(
[Object Schema] sysname NULL,
[Object Name] sysname NULL,
[Object Type] sysname NULL,
[TEXT Location] NVARCHAR(MAX) NULL,
[Position] NVARCHAR(1000)
);
END
-- Table names
IF @Table = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(IIF(@DatabaseName IS NOT NULL,N'USE [' + @DatabaseName + '];',N''),N'
INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'TABLE_SCHEMA AS [Object Schema]
,TABLE_NAME AS [Object Name]
,TABLE_TYPE AS [Object Type]
,''Table Name'' AS [TEXT Location]
,NULL
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = N''BASE TABLE''
AND TABLE_NAME LIKE ''%''+@Text+''%''');
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search Table on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
--Column names| computed_columns
IF @Column = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(IIF(@DatabaseName IS NOT NULL,N'USE [' + @DatabaseName + '];',N''),N'
INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'TABLE_SCHEMA AS [Object Schema]
,TABLE_NAME AS [Object Name]
,''COLUMN'' AS [Object Type]
,COLUMN_NAME AS [TEXT Location]
,NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE ''%''+@Text+''%''
UNION ALL
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,o.type_desc AS [Object Type]
,C.definition AS [TEXT Location]
,NULL
FROM sys.computed_columns C
INNER JOIN sys.objects o ON C.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE C.definition Like ''%''+@Text+''%''
') ;
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search Column on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
--PROCEDURE
IF @Procedure = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(
N'INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,''PROCEDURE'' AS [Object Type]
,m.definition AS [TEXT Location]
,SUBSTRING(m.definition,PATINDEX(''%''+@Text+''%'',m.definition),100)
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id=o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE m.definition Like ''%''+@Text+''%''
and o.type = ''P''');
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search Procedure on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
-- FUNCTION
IF @Function = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(
N'INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,''FUNCTION('' + o.type + '')'' COLLATE SQL_Latin1_General_CP1_CI_AS AS [Object Type]
,m.definition AS [TEXT Location]
,SUBSTRING(m.definition,PATINDEX(''%''+@Text+''%'',m.definition),100)
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE m.definition Like ''%''+@Text+''%''
and o.type in (''FN'',''AF'',''FS'',''FT'',''IF'',''TF'')');
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search Function on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
-- Trigger
IF @Trigger = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(
N'INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,''FUNCTION('' + o.type + '')'' COLLATE SQL_Latin1_General_CP1_CI_AS AS [Object Type]
,m.definition AS [TEXT Location]
,SUBSTRING(m.definition,PATINDEX(''%''+@Text+''%'',m.definition),100)
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE m.definition Like ''%''+@Text+''%''
and o.type = ''TR''');
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search Trigger on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
--View
IF @View = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(
N'INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,o.type_desc COLLATE SQL_Latin1_General_CP1_CI_AS AS [Object Type]
,m.definition AS [TEXT Location]
,SUBSTRING(m.definition,PATINDEX(''%''+@Text+''%'',m.definition),100)
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE m.definition Like ''%''+@Text+''%''
and o.type = ''v''');
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search View on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
--default_constraints| check_constraints
IF @Constreint = 1
BEGIN
OPEN curDatabases;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = CONCAT(
N'INSERT #',IIF(@IsAllDatabases = 1,'DB',''),'Result
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,o.type_desc AS [Object Type]
,D.definition AS [TEXT Location]
,SUBSTRING(D.definition,PATINDEX(''%''+@Text+''%'',D.definition),100)
FROM sys.default_constraints D
INNER JOIN sys.objects o ON D.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE D.definition Like ''%''+@Text+''%''
UNION ALL
SELECT ',IIF(@IsAllDatabases = 1,'DB_NAME(),',''),'s.name AS [Object Schema]
,o.name AS [Object Name]
,o.type_desc AS [Object Type]
,C.definition AS [TEXT Location]
,SUBSTRING(D.definition,PATINDEX(''%''+@Text+''%'',C.definition),100)
FROM sys.check_constraints C
INNER JOIN sys.objects o ON C.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE C.definition Like ''%''+@Text+''%''');
EXEC sp_executesql @cmd, N'@Text nvarchar(4000)', @Text = @Text;
SET @Print = CONCAT('Search Constreint on ',@DatabaseName,' complete.');
RAISERROR (@Print, 10, 1) WITH NOWAIT;
FETCH NEXT FROM curDatabases INTO @DatabaseName;
END
CLOSE curDatabases;
END;
IF OBJECT_ID('tempdb..#DBResult') IS NOT NULL
BEGIN
SELECT *
FROM #DBResult
WHERE @IsExactMatch = 0
OR (@IsExactMatch = 1 AND [Object Name] = @Text);
DROP TABLE #DBResult;
END
IF OBJECT_ID('tempdb..#Result') IS NOT NULL
BEGIN
SELECT *
FROM #Result
WHERE @IsExactMatch = 0
OR (@IsExactMatch = 1 AND [Object Name] = @Text);
DROP TABLE #Result;
END
END;
END;
-- Job
IF @Job = 1
BEGIN
DECLARE @PreviewTextSize INT = 100;
SELECT 'Job Steps' AS SearchType,
j.[name] AS [Job Name],
s.step_id AS [Step #],
REPLACE(
REPLACE(
SUBSTRING(s.command, CHARINDEX(@Text, s.command) - @PreviewTextSize / 2, @PreviewTextSize),
CHAR(13) + CHAR(10),
''),
@Text,
'***' + @Text + '***') AS Command
FROM msdb.dbo.sysjobs j
INNER JOIN msdb.dbo.sysjobsteps s ON j.job_id = s.job_id
WHERE s.command LIKE '%' + @Text + '%';
END;
-- SSRS
IF @ReportServer = 1
BEGIN
IF EXISTS (SELECT TOP (1) 1 FROM sys.databases WHERE name = 'ReportServer')
BEGIN;
WITH cte AS
(
--gets the RDL; note the double convert.
SELECT [Path],
[Name] AS Report_Name,
CONVERT(XML, CONVERT(VARBINARY(MAX), Content)) AS rdl
FROM ReportServer.dbo.Catalog)
SELECT LEFT([Path], LEN([Path]) - CHARINDEX('/', REVERSE([Path])) + 1) AS Report_Path,
Report_Name,
T1.N.value('@Name', 'nvarchar(128)') AS DataSetName,
T2.N.value('(*:DataSourceName/text())[1]', 'nvarchar(128)') AS DataSourceName,
ISNULL(T2.N.value('(*:CommandType/text())[1]', 'nvarchar(128)'), 'T-SQL') AS CommandType,
T2.N.value('(*:CommandText/text())[1]', 'nvarchar(max)') AS CommandText
INTO #SSRS
FROM cte AS T
CROSS APPLY T.rdl.nodes('/*:Report/*:DataSets/*:DataSet') AS T1(N)
CROSS APPLY T1.N.nodes('*:Query') AS T2(N)
ORDER BY Report_Path,
Report_Name,
DataSetName,
DataSourceName,
CommandType,
CommandText;
SELECT *
FROM #SSRS
WHERE CommandText LIKE '%' + @Text + '%';
END;
DEALLOCATE curDatabases;
END;
但是,如果您与 EF o Nhibernate 一起工作,您将处于困境
我发现我可以使用 SQL 句柄字符串获取死锁中每个查询的完整 SQL 文本(SQL 句柄包含在死锁图中/XDL ).
例如,死锁内 XML:
<frame procname="adhoc" line="1" stmtend="368" sqlhandle="0x02000000309a63065dbc0db09405222fe0f66eb954ed1d870000000000000000000000000000000000000000">
将 sqlhandle 传递给 sys.dm_exec_sql_text
SELECT * FROM sys.dm_exec_sql_text(0x02000000309a63065dbc0db09405222fe0f66eb954ed1d870000000000000000000000000000000000000000000000000000000000000000000000000) -- modify this value with your actual sql_handle