USE [NutsAndBolts]
GO
/****** Object: StoredProcedure [dbo].[alert_AlterFailedJobInfo] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: auto alter failed schedule job info
-- =============================================
CREATE PROCEDURE [dbo].[alert_AlterFailedJobInfo]
@p_JobName VARCHAR(255) = NULL, -- Optional job name filter
@p_ShowDisabled BIT = 0, -- Include disabled jobs?
@p_ShowUnscheduled BIT = 0, -- Include Unscheduled jobs?
@p_JobThresholdSec INT = 0, -- If positive, show only the jobs with LAST duration above this.
@p_AvgExecThresholdSec INT = 0 -- If positive, show only the jobs with AVERAGE duration above this.
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * INTO #TJob
FROM ( SELECT JobName,
ISNULL(LastStep,'') LastStep,
CASE WHEN StartDate IS NOT NULL AND FinishDate IS NULL THEN 'Running'
WHEN Enabled = 0 THEN 'Disabled'
WHEN StepCount = 0 THEN 'No steps'
WHEN RunStatus IS NOT NULL THEN RunStatus
WHEN ScheduleCount = 0 THEN 'Not scheduled'
ELSE 'UNKNOWN' END Info,
DatabaseName,
Enabled,
ScheduleCount,
StepCount,
StartDate,
FinishDate,
DurationSec,
RIGHT('0'+convert(varchar(5),DurationSec/3600),2)+':'+
RIGHT('0'+convert(varchar(5),DurationSec%3600/60),2)+':'+
RIGHT('0'+convert(varchar(5),(DurationSec%60)),2) DurationSecFormatted,
avgDurationSec,
RIGHT('0'+convert(varchar(5),avgDurationSec/3600),2)+':'+
RIGHT('0'+convert(varchar(5),avgDurationSec%3600/60),2)+':'+
RIGHT('0'+convert(varchar(5),(avgDurationSec%60)),2) avgDurationSecFormatted,
CASE WHEN (DurationSec IS NULL OR ISNULL(avgDurationSec, 0) = 0) THEN 0
ELSE CONVERT(DECIMAL(18,2), (100*CAST(DurationSec AS DECIMAL)) / CAST (avgDurationSec as DECIMAL)) END AS DurationRatio,
NextRunDate,
StepCommand,
HistoryMessage
FROM ( SELECT j.name JobName,
j.enabled Enabled,
(SELECT COUNT(1) FROM msdb..sysjobschedules jss WHERE jss.job_id = j.job_id) ScheduleCount,
(SELECT COUNT(1) FROM msdb..sysjobsteps jps WHERE jps.job_id = j.job_id) StepCount,
ls1.job_history_id HistoryID,
ls1.start_execution_date StartDate,
ls1.stop_execution_date FinishDate,
ls1.last_executed_step_id LastStepID,
DATEDIFF(SECOND,
ls1.start_execution_date,
CASE WHEN ls1.stop_execution_date IS NULL THEN GETDATE()
ELSE ls1.stop_execution_date END) DurationSec,
ISNULL(avgSec, 0) avgDurationSec,
ls1.next_scheduled_run_date NextRunDate,
st.step_name LastStep,
st.command StepCommand,
st.database_name DatabaseName,
h.message HistoryMessage,
CASE WHEN h.job_id IS NULL THEN 'Never Run'
ELSE CASE h.run_status WHEN 0 THEN 'Failed'
WHEN 1 THEN 'Succeeded'
WHEN 2 THEN 'Retry'
WHEN 3 THEN 'Canceled' END END RunStatus,
h.run_date rawRunDate,
h.run_time rawRunTime,
h.run_duration rawRunDuration
FROM msdb..sysjobactivity ls1 (NOLOCK)
INNER JOIN msdb..sysjobs j (NOLOCK) ON ls1.job_id = j.job_id
INNER JOIN (SELECT job_id JobID,
MAX(session_id) LastSessionID
FROM msdb..sysjobactivity (NOLOCK)
GROUP BY job_id ) ls2 ON ls1.job_id = ls2.JobID
AND ls1.session_id = ls2.LastSessionID
LEFT OUTER JOIN msdb..sysjobsteps st (NOLOCK) ON st.job_id = j.job_id
AND ls1.last_executed_step_id = st.step_id
LEFT OUTER JOIN msdb..sysjobhistory h (NOLOCK) ON h.instance_id = ls1.job_history_id
LEFT OUTER JOIN ( SELECT j.job_id JobID,
SUM(h.avgSecs) avgSec
FROM msdb..sysjobs j (NOLOCK)
INNER JOIN ( SELECT job_id,
step_id,
AVG(run_duration/10000*3600 +
run_duration%10000/100*60 +
run_duration%100) avgSecs
FROM msdb..sysjobhistory
WHERE step_id > 0
AND run_status = 1
GROUP BY job_id,
step_id ) h ON j.job_id = h.job_id
GROUP BY j.job_id ) jobavg ON jobavg.JobID = j.job_id )jj
WHERE (@p_ShowDisabled = 1 OR (StartDate IS NOT NULL AND FinishDate IS NULL) OR Enabled = 1)
AND (@p_JobName IS NULL OR JobName = @p_JobName)
AND (@p_ShowUnscheduled = 1 OR (StartDate IS NOT NULL AND FinishDate IS NULL) OR ScheduleCount > 0)
AND (@p_JobThresholdSec = 0 OR DurationSec >= @p_JobThresholdSec)
AND (@p_AvgExecThresholdSec = 0 OR avgDurationSec >= @p_AvgExecThresholdSec))x
ORDER BY CASE Info
WHEN 'Running' THEN 0
WHEN 'Failed' THEN 1
WHEN 'Retry' THEN 2
WHEN 'Succeeded' THEN 3
WHEN 'Canceled' THEN 4
WHEN 'No steps' THEN 5
WHEN 'Not scheduled' THEN 6
WHEN 'Disabled' THEN 7
WHEN 'Never Run' THEN 8
WHEN 'UNKNOWN' THEN -1
ELSE -2 END,
NextRunDate,
JobName
--send alert report part
IF EXISTS(SELECT 1 FROM #TJob WHERE Info IN ('Failed') )
BEGIN
SELECT * INTO #TReport FROM #TJob WHERE Info IN ('Failed')
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Alert Failed Job'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
END
DROP TABLE #TJob
END
GO
/****** Object: StoredProcedure [dbo].[dbm_KillInactiveConnection] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-06
-- Description: kill the inactive connection which last 1 minute
-- =============================================
CREATE PROCEDURE [dbo].[dbm_KillInactiveConnection]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE cConnections CURSOR READ_ONLY FAST_FORWARD FOR
SELECT spid
FROM master..sysprocesses p
INNER JOIN master..syslogins l ON p.sid = l.sid
WHERE l.loginname LIKE 'MSDOMAIN1\%' AND l.loginname NOT IN ('MSDOMAIN1\xzhang3', 'MSDOMAIN1\ouli', 'MSDOMAIN1\atian1')
AND p.last_batch <= DATEADD(mi, -1, GETDATE())
DECLARE @l_ConnectionId INT,
@l_Sql VARCHAR(100)
OPEN cConnections
WHILE 1 = 1
BEGIN
FETCH NEXT FROM cConnections INTO @l_ConnectionId
IF @@FETCH_STATUS <> 0
BREAK
SET @l_Sql = 'KILL ' + CONVERT(VARCHAR, @l_ConnectionId)
EXECUTE( @l_Sql )
END
CLOSE cConnections
DEALLOCATE cConnections
END
GO
/****** Object: StoredProcedure [dbo].[demo_EmailHtmlTableAlert] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- Purpose: a template for sending alert script part
-- Create Date: 08/29/2012
-- Last Update: 08/29/2012
-- Author: Alex Tian
CREATE PROCEDURE [dbo].[demo_EmailHtmlTableAlert]
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
--generate a temp table
SELECT TOP 10 * INTO #TAlert FROM master.sys.objects
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailObject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailObject='demo_EmailHtmlTableAlert'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TAlert')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.Fn_splitstringtoquerycolumn(@l_TColumn, ',')
SET @l_HHeader=dbo.Fn_splitstringtohtmlheader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TAlert AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE Sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.Fn_formathtmltable(@l_Html, @l_HHeader)
EXECUTE dbo.Utility_emailhtmlstringtohtmltable @p_Subject=@l_EmailObject,
@p_HtmlString=@l_EmailBody
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportIndexFragementInfoForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: report frgement info for all databases on a given server
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportIndexFragementInfoForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
CREATE TABLE #FragmentedIndexes
( DatabaseName NVARCHAR(200),
SchemaName NVARCHAR(200),
TableName NVARCHAR(200),
IndexName NVARCHAR(200),
[Fragmentation%] FLOAT )
EXEC sp_MSforeachdb 'USE [?];
INSERT INTO #FragmentedIndexes
SELECT DB_NAME(DB_ID()) AS DatabaseName,
sc.name AS SchemaName,
OBJECT_NAME (s.object_id) AS TableName,
i.name AS IndexName,
s.avg_fragmentation_in_percent AS [Fragmentation%]
FROM sys.dm_db_index_physical_stats(db_id(),NULL, NULL, NULL,''SAMPLED'') s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON sc.[schema_id] = o.[schema_id]
WHERE s.database_id = DB_ID()
AND i.index_id != 0
AND s.record_count > 0
AND s.avg_fragmentation_in_percent>5
AND o.is_ms_shipped = 0 ;'
--Generate rebuild/reorganize index script
SELECT
CASE WHEN [Fragmentation%] > 30
THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(DatabaseName) + '.'+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName) + ' REBUILD;'
WHEN [Fragmentation%] > 10
THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(DatabaseName) + '.'+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName) + ' REORGANIZE;' END AS MaintanceScript
INTO #TScript
FROM #FragmentedIndexes
WHERE [Fragmentation%] > 10
--send alert report part
IF EXISTS(SELECT 1 FROM #FragmentedIndexes WHERE [Fragmentation%]>=10 )
BEGIN
SELECT * INTO #TReport FROM #FragmentedIndexes WHERE [Fragmentation%]>=10
SELECT * INTO #TReport1 FROM #TScript
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
--for #TReport part
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Index Fragement List For All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
--for #TReport1 part
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Index Fragement Maintance Script For All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport1')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport1 AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
DROP TABLE #TReport1
END
DROP TABLE #FragmentedIndexes
DROP TABLE #TScript
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportJobSummaryInfo] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get job summary
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportJobSummaryInfo]
@p_JobName VARCHAR(255) = NULL, -- Optional job name filter
@p_ShowDisabled BIT = 0, -- Include disabled jobs?
@p_ShowUnscheduled BIT = 0, -- Include Unscheduled jobs?
@p_JobThresholdSec INT = 0, -- If positive, show only the jobs with LAST duration above this.
@p_AvgExecThresholdSec INT = 0 -- If positive, show only the jobs with AVERAGE duration above this.
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * INTO #TJob
FROM ( SELECT JobName,
ISNULL(LastStep,'') LastStep,
CASE WHEN StartDate IS NOT NULL AND FinishDate IS NULL THEN 'Running'
WHEN Enabled = 0 THEN 'Disabled'
WHEN StepCount = 0 THEN 'No steps'
WHEN RunStatus IS NOT NULL THEN RunStatus
WHEN ScheduleCount = 0 THEN 'Not scheduled'
ELSE 'UNKNOWN' END Info,
DatabaseName,
Enabled,
ScheduleCount,
StepCount,
StartDate,
FinishDate,
DurationSec,
RIGHT('0'+convert(varchar(5),DurationSec/3600),2)+':'+
RIGHT('0'+convert(varchar(5),DurationSec%3600/60),2)+':'+
RIGHT('0'+convert(varchar(5),(DurationSec%60)),2) DurationSecFormatted,
avgDurationSec,
RIGHT('0'+convert(varchar(5),avgDurationSec/3600),2)+':'+
RIGHT('0'+convert(varchar(5),avgDurationSec%3600/60),2)+':'+
RIGHT('0'+convert(varchar(5),(avgDurationSec%60)),2) avgDurationSecFormatted,
CASE WHEN (DurationSec IS NULL OR ISNULL(avgDurationSec, 0) = 0) THEN 0
ELSE CONVERT(DECIMAL(18,2), (100*CAST(DurationSec AS DECIMAL)) / CAST (avgDurationSec as DECIMAL)) END AS DurationRatio,
NextRunDate,
StepCommand,
HistoryMessage
FROM ( SELECT j.name JobName,
j.enabled Enabled,
(SELECT COUNT(1) FROM msdb..sysjobschedules jss WHERE jss.job_id = j.job_id) ScheduleCount,
(SELECT COUNT(1) FROM msdb..sysjobsteps jps WHERE jps.job_id = j.job_id) StepCount,
ls1.job_history_id HistoryID,
ls1.start_execution_date StartDate,
ls1.stop_execution_date FinishDate,
ls1.last_executed_step_id LastStepID,
DATEDIFF(SECOND,
ls1.start_execution_date,
CASE WHEN ls1.stop_execution_date IS NULL THEN GETDATE()
ELSE ls1.stop_execution_date END) DurationSec,
ISNULL(avgSec, 0) avgDurationSec,
ls1.next_scheduled_run_date NextRunDate,
st.step_name LastStep,
st.command StepCommand,
st.database_name DatabaseName,
h.message HistoryMessage,
CASE WHEN h.job_id IS NULL THEN 'Never Run'
ELSE CASE h.run_status WHEN 0 THEN 'Failed'
WHEN 1 THEN 'Succeeded'
WHEN 2 THEN 'Retry'
WHEN 3 THEN 'Canceled' END END RunStatus,
h.run_date rawRunDate,
h.run_time rawRunTime,
h.run_duration rawRunDuration
FROM msdb..sysjobactivity ls1 (NOLOCK)
INNER JOIN msdb..sysjobs j (NOLOCK) ON ls1.job_id = j.job_id
INNER JOIN (SELECT job_id JobID,
MAX(session_id) LastSessionID
FROM msdb..sysjobactivity (NOLOCK)
GROUP BY job_id ) ls2 ON ls1.job_id = ls2.JobID
AND ls1.session_id = ls2.LastSessionID
LEFT OUTER JOIN msdb..sysjobsteps st (NOLOCK) ON st.job_id = j.job_id
AND ls1.last_executed_step_id = st.step_id
LEFT OUTER JOIN msdb..sysjobhistory h (NOLOCK) ON h.instance_id = ls1.job_history_id
LEFT OUTER JOIN ( SELECT j.job_id JobID,
SUM(h.avgSecs) avgSec
FROM msdb..sysjobs j (NOLOCK)
INNER JOIN ( SELECT job_id,
step_id,
AVG(run_duration/10000*3600 +
run_duration%10000/100*60 +
run_duration%100) avgSecs
FROM msdb..sysjobhistory
WHERE step_id > 0
AND run_status = 1
GROUP BY job_id,
step_id ) h ON j.job_id = h.job_id
GROUP BY j.job_id ) jobavg ON jobavg.JobID = j.job_id )jj
WHERE (@p_ShowDisabled = 1 OR (StartDate IS NOT NULL AND FinishDate IS NULL) OR Enabled = 1)
AND (@p_JobName IS NULL OR JobName = @p_JobName)
AND (@p_ShowUnscheduled = 1 OR (StartDate IS NOT NULL AND FinishDate IS NULL) OR ScheduleCount > 0)
AND (@p_JobThresholdSec = 0 OR DurationSec >= @p_JobThresholdSec)
AND (@p_AvgExecThresholdSec = 0 OR avgDurationSec >= @p_AvgExecThresholdSec))x
ORDER BY CASE Info
WHEN 'Running' THEN 0
WHEN 'Failed' THEN 1
WHEN 'Retry' THEN 2
WHEN 'Succeeded' THEN 3
WHEN 'Canceled' THEN 4
WHEN 'No steps' THEN 5
WHEN 'Not scheduled' THEN 6
WHEN 'Disabled' THEN 7
WHEN 'Never Run' THEN 8
WHEN 'UNKNOWN' THEN -1
ELSE -2 END,
NextRunDate,
JobName
--send alert report part
IF EXISTS(SELECT 1 FROM #TJob )
BEGIN
SELECT * INTO #TReport FROM #TJob
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Job Summary'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
END
DROP TABLE #TJob
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportTopLongestBlockedQueryForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Report the queries spend the longest time being blocked for all database
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportTopLongestBlockedQueryForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
CAST((qs.total_elapsed_time - qs.total_worker_time) /1000000.0 AS DECIMAL(28,2)) AS [Total time blocked (s)],
CAST(qs.total_worker_time * 100.0 / qs.total_elapsed_time AS DECIMAL(28,2)) AS [% CPU],
CAST((qs.total_elapsed_time - qs.total_worker_time)* 100.0 /qs.total_elapsed_time AS DECIMAL(28, 2)) AS [% Waiting],
qs.execution_count,
CAST((qs.total_elapsed_time - qs.total_worker_time) / 1000000.0/ qs.execution_count AS DECIMAL(28, 2)) AS [Blocking average (s)],
SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1,((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query],
qt.text AS [Parent Query],
DB_NAME(qt.dbid) AS DatabaseName
--qp.query_plan
INTO #TResult
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qs.total_elapsed_time > 0
ORDER BY [Total time blocked (s)] DESC
--send alert report part
IF EXISTS(SELECT 1 FROM #TResult )
BEGIN
SELECT * INTO #TReport FROM #TResult
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Top Longest Blocked Query List'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
END
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportTopLongestTimeQueryForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: The queries that take the longest time to run for all database
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportTopLongestTimeQueryForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
CAST(qs.total_elapsed_time / 1000000.0 AS DECIMAL(28, 2))AS [Total Duration (s)],
CAST(qs.total_worker_time * 100.0 / qs.total_elapsed_time AS DECIMAL(28, 2))AS [% CPU],
CAST((qs.total_elapsed_time - qs.total_worker_time)* 100.0 /qs.total_elapsed_time AS DECIMAL(28, 2)) AS [% Waiting],
qs.execution_count,
CAST(qs.total_elapsed_time / 1000000.0 / qs.execution_count AS DECIMAL(28, 2))AS [Average Duration (s)],
SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1,((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query],
qt.text AS [Parent Query],
DB_NAME(qt.dbid) AS DatabaseName
--qp.query_plan
INTO #TResult
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qs.total_elapsed_time > 0
ORDER BY qs.total_elapsed_time DESC
--send alert report part
IF EXISTS(SELECT 1 FROM #TResult )
BEGIN
SELECT * INTO #TReport FROM #TResult
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Top Longest Time Cost Query List For All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
END
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportTopMissingIndexForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Report the top missing index for all database
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportTopMissingIndexForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
'CREATE NONCLUSTERED INDEX '+
QUOTENAME('IX_AutoGenerated_'+
REPLACE(REPLACE(CONVERT(VARCHAR(25), GETDATE(), 113), ' ', '_'), ':', '_')+
'_' + CAST(d.index_handle AS VARCHAR(22)))+ ' ON ' + d.[statement] +
'('+ CASE
WHEN d.equality_columns IS NULL THEN d.inequality_columns
WHEN d.inequality_columns IS NULL THEN d.equality_columns
ELSE d.equality_columns + ',' + d.inequality_columns END + ')'+
CASE WHEN d.included_columns IS NOT NULL THEN ' INCLUDE ( ' + d.included_columns + ')'
ELSE '' END AS MissingIndexSQL,
ROUND(s.avg_total_user_cost * s.avg_user_impact * (s.user_seeks + s.user_scans),0) AS [Total Cost],
d.[statement] AS [Table Name],
d.equality_columns,
d.inequality_columns,
d.included_columns
INTO #MissingIndexes
FROM sys.dm_db_missing_index_groups g
INNER JOIN sys.dm_db_missing_index_group_stats s ON s.group_handle = g.index_group_handle
INNER JOIN sys.dm_db_missing_index_details d ON d.index_handle = g.index_handle
ORDER BY [Total Cost] DESC
SELECT MissingIndexSQL AS MaintanceScript INTO #TScript
FROM #MissingIndexes
--send alert report part
IF EXISTS(SELECT 1 FROM #MissingIndexes)
BEGIN
SELECT * INTO #TAlert FROM #MissingIndexes
SELECT * INTO #TAlert1 FROM #TScript
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
--for #TAlert part
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Top Missing Index List For All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TAlert')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TAlert AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
--for #TAlert1 part
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Top Missing Index Maintance Script For All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TAlert1')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TAlert1 AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TAlert
DROP TABLE #TAlert1
END
DROP TABLE #MissingIndexes
DROP TABLE #TScript
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportTopMostCPUCostQueryForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Report the queries that use the most CPU for all database
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportTopMostCPUCostQueryForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
CAST((qs.total_worker_time) / 1000000.0AS DECIMAL(28,2)) AS [Total CPU time (s)],
CAST(qs.total_worker_time * 100.0 / qs.total_elapsed_time AS DECIMAL(28,2)) AS [% CPU],
CAST((qs.total_elapsed_time - qs.total_worker_time)* 100.0 /qs.total_elapsed_time AS DECIMAL(28, 2)) AS [% Waiting],
qs.execution_count,
CAST((qs.total_worker_time) / 1000000.0/ qs.execution_count AS DECIMAL(28, 2)) AS [CPU time average (s)],
SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1,((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query],
qt.text AS [Parent Query],
DB_NAME(qt.dbid) AS DatabaseName
--qp.query_plan
INTO #TResult
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qs.total_elapsed_time > 0
ORDER BY [Total CPU time (s)] DESC
--send alert report part
IF EXISTS(SELECT 1 FROM #TResult )
BEGIN
SELECT * INTO #TReport FROM #TResult
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Top More CUP Cost Query List For All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
END
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportTopMostIOCostQueryForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Report the queries that use the most I/O
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportTopMostIOCostQueryForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
[Total IO] = (qs.total_logical_reads + qs.total_logical_writes),
[Average IO] = (qs.total_logical_reads + qs.total_logical_writes) /qs.execution_count,
qs.execution_count,
SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1,((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query],
qt.text AS [Parent Query],
DB_NAME(qt.dbid) AS DatabaseName
--qp.query_plan
INTO #TResult
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY [Total IO] DESC
--send alert report part
IF EXISTS(SELECT 1 FROM #TResult )
BEGIN
SELECT * INTO #TReport FROM #TResult
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Top More IO Cost Query List For All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
END
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportTopMostOftenExecutedQueryForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Report the queries that have been executed the most often
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportTopMostOftenExecutedQueryForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
qs.execution_count,
SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1,((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query],
qt.text AS [Parent Query],
DB_NAME(qt.dbid) AS DatabaseName
--qp.query_plan
INTO #TResult
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY qs.execution_count DESC;
--send alert report part
IF EXISTS(SELECT 1 FROM #TResult )
BEGIN
SELECT * INTO #TReport FROM #TResult
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Top More Most Often Executed Query List For All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
END
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportTopMostRecompiledQueryForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Report the most-recompiled queries
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportTopMostRecompiledQueryForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
qs.plan_generation_num,
qs.total_elapsed_time,
qs.execution_count,
SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1,((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query],
qt.text AS [Parent Query],
DB_NAME(qt.dbid) AS DBName,
qs.creation_time,
qs.last_execution_time
INTO #TResult
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
ORDER BY plan_generation_num DESC
--send alert report part
IF EXISTS(SELECT 1 FROM #TResult )
BEGIN
SELECT * INTO #TReport FROM #TResult
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Top More Most Recompiled Query List For All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
END
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportUnusedIndexForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Report unused indexes for all database
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportUnusedIndexForAllDatabase]
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NOCOUNT ON
SELECT DB_NAME() AS DatabaseName,
SCHEMA_NAME(o.Schema_ID) AS SchemaName,
OBJECT_NAME(s.[object_id]) AS TableName,
i.name AS IndexName,
s.user_updates,
s.system_seeks + s.system_scans + s.system_lookups AS [System usage]
INTO #TempUnusedIndexes
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
INNER JOIN sys.objects o ON i.object_id = o.object_id
WHERE 1=2
EXEC sp_MSforeachdb 'USE [?];
INSERT INTO #TempUnusedIndexes
SELECT TOP 20
DB_NAME() AS DatabaseName,
SCHEMA_NAME(o.Schema_ID) AS SchemaName,
OBJECT_NAME(s.[object_id]) AS TableName,
i.name AS IndexName,
s.user_updates,
s.system_seeks + s.system_scans + s.system_lookups AS [System usage]
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
INNER JOIN sys.objects o ON i.object_id = o.object_id
WHERE s.database_id = DB_ID()
AND OBJECTPROPERTY(s.[object_id], ''IsMsShipped'') = 0
AND user_seeks = 0
AND user_scans = 0
AND user_lookups = 0
AND i.name IS NOT NULL
ORDER BY user_updates DESC'
DECLARE @DisableOrDrop INT
DECLARE @DisableIndexesSQL NVARCHAR(MAX)
SET @DisableOrDrop = 1
SET @DisableIndexesSQL = ''
SELECT CASE
WHEN @DisableOrDrop = 1
THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(DatabaseName) + '.'+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName) + ' DISABLE;'
ELSE CHAR(10) + 'DROP INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(DatabaseName) + '.'+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName)
END AS MaintanceScript INTO #TScript
FROM #TempUnusedIndexes
--send alert report part
IF EXISTS(SELECT 1 FROM #TempUnusedIndexes )
BEGIN
SELECT * INTO #TReport FROM #TempUnusedIndexes
SELECT * INTO #TReport1 FROM #TScript
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
--for #TReport part
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Unused Index List For All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
--for #TReport1 part
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Unused Index Maintance Script For All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport1')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport1 AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
DROP TABLE #TReport1
END
DROP TABLE #TempUnusedIndexes
DROP TABLE #TScript
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportWeeklyBackupEvaluationForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get backup evaluated info for all database
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportWeeklyBackupEvaluationForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT a.server_name AS 'Server',
a.database_name AS 'Database',
CONVERT(VARCHAR(25), a.backup_start_date,100) AS 'Start Date',
CONVERT(VARCHAR(25), a.backup_finish_date,100) AS 'Finish Date',
DATENAME(WEEKDAY, a.backup_finish_date) AS 'Day' ,
DATEDIFF(MILLISECOND , a.backup_start_date, a.backup_finish_date) AS 'MSec' ,
DATEDIFF(SECOND, a.backup_start_date, a.backup_finish_date) AS 'Sec' ,
DATEDIFF(MINUTE, a.backup_start_date, a.backup_finish_date) AS 'Mins' ,
CAST(CAST(DATEDIFF(MINUTE, a.backup_start_date, a.backup_finish_date) AS DECIMAL(8,3))/60 AS DECIMAL(8,1)) AS 'Hours',
CASE WHEN DATEDIFF(MINUTE, a.backup_start_date, a.backup_finish_date) > 0
THEN CAST(CEILING(a.backup_size /1048576) / DATEDIFF(MINUTE, a.backup_start_date, a.backup_finish_date) AS DECIMAL(8,1))
ELSE 0
END AS 'Meg/Min',
CEILING(a.backup_size /1048576) AS 'Size Meg',
CAST((a.backup_size /1073741824) AS DECIMAL(9,2)) AS 'Gig',
a.user_name,a.backup_size AS 'Raw Size'
INTO #TResult
FROM msdb.dbo.backupset a
JOIN msdb.dbo.backupset b ON a.server_name = b.server_name AND a.database_name = b.database_name
WHERE a.type = 'D'
AND b.type = 'D'
AND DATEDIFF(WEEKDAY,a.backup_start_date,GETDATE())<=7
GROUP BY a.server_name, a.database_name, a.backup_start_date, a.backup_finish_date, a.backup_size, a.user_name
ORDER BY a.server_name DESC , a.database_name,a.backup_start_date DESC
--send alert report part
IF EXISTS(SELECT 1 FROM #TResult )
BEGIN
SELECT * INTO #TReport FROM #TResult
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report The Lastest Week Backup Evaluation'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
END
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportWeeklyDiskSpaceTrend] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportTheLatestWeekEventLog] Script Date: 2012/9/6 17:29:49 ******/
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: auto report daily disk space trend
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportWeeklyDiskSpaceTrend]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @l_BeginDate SMALLDATETIME
DECLARE @l_EndDate SMALLDATETIME
DECLARE @l_DateNow SMALLDATETIME
SET @l_DateNow = CONVERT(VARCHAR(10), GETDATE(), 120)
SET @l_BeginDate = DATEADD(d, - DATEPART(dw, @l_DateNow) - 7, @l_DateNow)
SET @l_EndDate = DATEADD(d, - DATEPART(dw, @l_DateNow), @l_DateNow)
IF EXISTS ( SELECT 1
FROM dbo.AvailableDiskSpace
WHERE LastUpdate >= @l_BeginDate
AND LastUpdate < @l_EndDate )
BEGIN
SELECT *
INTO #TResult
FROM dbo.AvailableDiskSpace
WHERE LastUpdate >= @l_BeginDate
AND LastUpdate < @l_EndDate
ORDER BY DriveLetter,LastUpdate DESC
END
ELSE RETURN 0
--send alert report part
IF EXISTS(SELECT 1 FROM #TResult )
BEGIN
SELECT * INTO #TReport FROM #TResult
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Daily Disk Space Trend'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
END
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[rpt_ReportWeeklyEventLog] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: auto report event logs
-- =============================================
CREATE PROCEDURE [dbo].[rpt_ReportWeeklyEventLog]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @l_BeginDate SMALLDATETIME
DECLARE @l_EndDate SMALLDATETIME
DECLARE @l_DateNow SMALLDATETIME
SET @l_DateNow = CONVERT(VARCHAR(10), GETDATE(), 120)
SET @l_BeginDate = DATEADD(d, - DATEPART(dw, @l_DateNow) - 7, @l_DateNow)
SET @l_EndDate = DATEADD(d, - DATEPART(dw, @l_DateNow), @l_DateNow)
IF EXISTS ( SELECT 1
FROM dbo.EventLog
WHERE EventData.value('(/EVENT_INSTANCE/PostTime)[1]', 'smalldatetime') >= @l_BeginDate
AND EventData.value('(/EVENT_INSTANCE/PostTime)[1]', 'smalldatetime') < @l_EndDate )
BEGIN
SELECT EventData.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'varchar(128)') AS DatabaseName,
EventData.value('(/EVENT_INSTANCE/EventType)[1]', 'varchar(128)') AS EventType,
EventData.value('(/EVENT_INSTANCE/UserName)[1]', 'varchar(128)') AS UserName,
EventData.value('(/EVENT_INSTANCE/LoginName)[1]', 'varchar(128)') AS LoginName,
EventData.value('(/EVENT_INSTANCE/PostTime)[1]', 'datetime') AS PostTime,
EventData.value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)') AS CommandText
INTO #TResult
FROM dbo.EventLog
WHERE EventData.value('(/EVENT_INSTANCE/PostTime)[1]', 'smalldatetime') >= @l_BeginDate
AND EventData.value('(/EVENT_INSTANCE/PostTime)[1]', 'smalldatetime') < @l_EndDate
END
ELSE RETURN 0
--send alert report part
IF EXISTS(SELECT 1 FROM #TResult )
BEGIN
SELECT * INTO #TReport FROM #TResult
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Auto Report Latest Event Log'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TReport')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TReport AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TReport
END
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[utility_AUDIT_CheckDefaultStatisticsOptionForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Check statistics option default value
-- =============================================
CREATE PROCEDURE [dbo].[utility_AUDIT_CheckDefaultStatisticsOptionForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT name AS DatabaseName,
is_auto_create_stats_on AS AutoCreateStatistics,
is_auto_update_stats_on AS AutoUpdateStatistics,
is_auto_update_stats_async_on AS AutoUpdateStatisticsAsync
FROM sys.databases
ORDER BY DatabaseName
END
GO
/****** Object: StoredProcedure [dbo].[utility_AUDIT_CheckDisparateColumWithDifferentDataTypeForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Find disparate columns with different data types
-- =============================================
CREATE PROCEDURE [dbo].[utility_AUDIT_CheckDisparateColumWithDifferentDataTypeForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT DISTINCT
DB_NAME() AS DBName,
C1.COLUMN_NAME,
C1.TABLE_SCHEMA,
C1.TABLE_NAME,
C1.DATA_TYPE,
C1.CHARACTER_MAXIMUM_LENGTH,
C1.NUMERIC_PRECISION,
C1.NUMERIC_SCALE,
0 AS [%]
INTO #TResult
FROM INFORMATION_SCHEMA.COLUMNS C1
INNER JOIN INFORMATION_SCHEMA.COLUMNS C2 ON C1.COLUMN_NAME = C2.COLUMN_NAME
WHERE 1=2
EXEC sp_MSforeachdb 'USE [?];
SELECT COLUMN_NAME,
[%] = CONVERT(DECIMAL(12,2),COUNT(COLUMN_NAME)*100.0 / COUNT(*)OVER())
INTO #Prevalence
FROM INFORMATION_SCHEMA.COLUMNS
GROUP BY COLUMN_NAME
INSERT INTO #TResult
SELECT DISTINCT
DB_NAME() AS DBName,
C1.COLUMN_NAME,
C1.TABLE_SCHEMA,
C1.TABLE_NAME,
C1.DATA_TYPE,
C1.CHARACTER_MAXIMUM_LENGTH,
C1.NUMERIC_PRECISION,
C1.NUMERIC_SCALE,
[%]
FROM INFORMATION_SCHEMA.COLUMNS C1
INNER JOIN INFORMATION_SCHEMA.COLUMNS C2 ON C1.COLUMN_NAME = C2.COLUMN_NAME
INNER JOIN #Prevalence p ON p.COLUMN_NAME = C1.COLUMN_NAME
WHERE ((C1.DATA_TYPE != C2.DATA_TYPE)
OR (C1.CHARACTER_MAXIMUM_LENGTH != C2.CHARACTER_MAXIMUM_LENGTH)
OR (C1.NUMERIC_PRECISION != C2.NUMERIC_PRECISION)
OR (C1.NUMERIC_SCALE != C2.NUMERIC_SCALE))
ORDER BY [%] DESC, C1.COLUMN_NAME, C1.TABLE_SCHEMA, C1.TABLE_NAME ;'
SELECT * FROM #TResult
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[utility_AUDIT_CheckIdentityColumnInfoForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Check identity column info for all database
-- =============================================
CREATE PROCEDURE [dbo].[utility_AUDIT_CheckIdentityColumnInfoForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT DB_NAME() AS DBName,
QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name) AS TableName,
c.name AS ColumnName,
CASE c.system_type_id
WHEN 127 THEN 'bigint'
WHEN 56 THEN 'int'
WHEN 52 THEN 'smallint'
WHEN 48 THEN 'tinyint'
END AS DataType,
IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + '.' + t.name) AS CurrentIdentityValue,
CASE c.system_type_id
WHEN 127 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + '.' + t.name) * 100.) / 9223372036854775807
WHEN 56 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + '.' + t.name) * 100.) / 2147483647
WHEN 52 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + '.' + t.name) * 100.) / 32767
WHEN 48 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + '.' + t.name) * 100.) / 255
END AS PercentageUsed
INTO #TResult
FROM sys.columns AS c
INNER JOIN sys.tables AS t ON t.[object_id] = c.[object_id]
WHERE 1=2
EXEC sp_MSforeachdb 'USE [?];
INSERT INTO #TResult
SELECT DB_NAME() AS DBName,
QUOTENAME(SCHEMA_NAME(t.schema_id)) + ''.'' + QUOTENAME(t.name) AS TableName,
c.name AS ColumnName,
CASE c.system_type_id
WHEN 127 THEN ''bigint''
WHEN 56 THEN ''int''
WHEN 52 THEN ''smallint''
WHEN 48 THEN ''tinyint''
END AS DataType,
IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + ''.'' + t.name) AS CurrentIdentityValue,
CASE c.system_type_id
WHEN 127 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + ''.'' + t.name) * 100.) / 9223372036854775807
WHEN 56 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + ''.'' + t.name) * 100.) / 2147483647
WHEN 52 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + ''.'' + t.name) * 100.) / 32767
WHEN 48 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id) + ''.'' + t.name) * 100.) / 255
END AS PercentageUsed
FROM sys.columns AS c
INNER JOIN sys.tables AS t ON t.[object_id] = c.[object_id]
WHERE c.is_identity = 1
ORDER BY PercentageUsed DESC;'
SELECT * FROM #TResult ORDER BY DBName
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[utility_AUDIT_CheckTableWithoutClusteredIndexForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Find the tables without clustered index for all database
-- =============================================
CREATE PROCEDURE [dbo].[utility_AUDIT_CheckTableWithoutClusteredIndexForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT DB_NAME() AS DBName,
o.name
INTO #TResult
FROM sys.objects o
WHERE 1=2
EXEC sp_MSforeachdb 'USE [?];
INSERT INTO #TResult
SELECT DB_NAME() AS DBName,
o.name
FROM sys.objects o
WHERE o.type=''U''
AND NOT EXISTS(SELECT 1
FROM sys.indexes i
WHERE o.object_id = i.object_id
AND i.type_desc = ''CLUSTERED'');'
SELECT * FROM #TResult
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[utility_BACKUP_GetWeeklyBackupEvaluatedInfoForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get backup evaluated info for all database
-- =============================================
CREATE PROCEDURE [dbo].[utility_BACKUP_GetWeeklyBackupEvaluatedInfoForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT a.server_name AS 'Server',
a.database_name AS 'Database',
CONVERT(VARCHAR(25), a.backup_start_date,100) AS 'Start Date',
CONVERT(VARCHAR(25), a.backup_finish_date,100) AS 'Finish Date',
DATENAME(WEEKDAY, a.backup_finish_date) AS 'Day' ,
DATEDIFF(MILLISECOND , a.backup_start_date, a.backup_finish_date) AS 'MSec' ,
DATEDIFF(SECOND, a.backup_start_date, a.backup_finish_date) AS 'Sec' ,
DATEDIFF(MINUTE, a.backup_start_date, a.backup_finish_date) AS 'Mins' ,
CAST(CAST(DATEDIFF(MINUTE, a.backup_start_date, a.backup_finish_date) AS DECIMAL(8,3))/60 AS DECIMAL(8,1)) AS 'Hours',
CASE WHEN DATEDIFF(MINUTE, a.backup_start_date, a.backup_finish_date) > 0
THEN CAST(CEILING(a.backup_size /1048576) / DATEDIFF(MINUTE, a.backup_start_date, a.backup_finish_date) AS DECIMAL(8,1))
ELSE 0
END AS 'Meg/Min',
CEILING(a.backup_size /1048576) AS 'Size Meg',
CAST((a.backup_size /1073741824) AS DECIMAL(9,2)) AS 'Gig',
a.user_name,a.backup_size AS 'Raw Size'
FROM msdb.dbo.backupset a
JOIN msdb.dbo.backupset b ON a.server_name = b.server_name AND a.database_name = b.database_name
WHERE a.type = 'D'
AND b.type = 'D'
AND DATEDIFF(WEEKDAY,a.backup_start_date,GETDATE())<=7
GROUP BY a.server_name, a.database_name, a.backup_start_date, a.backup_finish_date, a.backup_size, a.user_name
ORDER BY a.server_name DESC , a.database_name,a.backup_start_date DESC
END
GO
/****** Object: StoredProcedure [dbo].[utility_BASIC_GetCPUUsageBasicInfo] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get CPU usage basic info
-- =============================================
CREATE PROCEDURE [dbo].[utility_BASIC_GetCPUUsageBasicInfo]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @ts_now BIGINT
SELECT @ts_now = cpu_ticks / CONVERT(FLOAT, cpu_ticks_in_ms)
FROM sys.dm_os_sys_info
SELECT RecordId,
DATEADD(ms, -1 * (@ts_now - [timestamp]), GETDATE()) AS EventTime,
SQLProcessUtilization,
SystemIdle,
100 - SystemIdle - SQLProcessUtilization AS OtherProcessUtilization
FROM ( SELECT timestamp,
record.value('(./Record/@id)[1]', 'int') AS RecordId,
record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') AS SystemIdle,
record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') AS SQLProcessUtilization
FROM (SELECT timestamp,
CONVERT(XML, record) AS record
FROM sys.dm_os_ring_buffers
WHERE ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR'
AND record LIKE '% %') AS x
) AS y
ORDER BY RecordId DESC
END
GO
/****** Object: StoredProcedure [dbo].[utility_BASIC_GetDatabaseBasicInfo] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get database basic info
-- =============================================
CREATE PROCEDURE [dbo].[utility_BASIC_GetDatabaseBasicInfo]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
IF EXISTS ( SELECT *
FROM tempdb.dbo.sysobjects
WHERE id = OBJECT_ID(N'[tempdb].[dbo].[HoldforEachDB]') )
DROP TABLE [tempdb].[dbo].[HoldforEachDB]
CREATE TABLE [tempdb].[dbo].[HoldforEachDB]
( [Server] [nvarchar](128) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[DatabaseName] [nvarchar](128) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Size] [int] NOT NULL,
[File_Status] [int] NULL,
[Name] [nvarchar](128) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Filename] [nvarchar](260) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Status] [nvarchar](128) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[Updateability] [nvarchar](128) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[User_Access] [nvarchar](128) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[Recovery] [nvarchar](128) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
INSERT INTO [tempdb].[dbo].[HoldforEachDB]
EXEC sp_MSforeachdb 'SELECT CONVERT(char(100), SERVERPROPERTY(''Servername'')) AS Server,
''?'' AS DatabaseName,
[?]..sysfiles.size,
[?]..sysfiles.status,
[?]..sysfiles.name,
[?]..sysfiles.filename,
CONVERT(sysname,DatabasePropertyEx(''?'',''Status'')) AS Status,
CONVERT(sysname,DatabasePropertyEx(''?'',''Updateability'')) AS Updateability,
CONVERT(sysname,DatabasePropertyEx(''?'',''UserAccess'')) AS User_Access,
CONVERT(sysname,DatabasePropertyEx(''?'',''Recovery'')) AS Recovery From [?]..sysfiles'
SELECT * FROM [tempdb].[dbo].[HoldforEachDB] ORDER BY DatabaseName
DROP TABLE [tempdb].[dbo].[HoldforEachDB]
END
GO
/****** Object: StoredProcedure [dbo].[utility_BASIC_GetSecurityBasicInfo] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get security basic info
-- =============================================
CREATE PROCEDURE [dbo].[utility_BASIC_GetSecurityBasicInfo]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
IF EXISTS ( SELECT *
FROM tempdb.dbo.sysobjects
WHERE id = OBJECT_ID(N'[tempdb].[dbo].[SQL_DB_REP]') )
DROP TABLE [tempdb].[dbo].[SQL_DB_REP] ;
CREATE TABLE [tempdb].[dbo].[SQL_DB_REP]
( [Server] [varchar](100) NOT NULL,
[DB_Name] [varchar](70) NOT NULL,
[User_Name] [nvarchar](90) NULL,
[Group_Name] [varchar](100) NULL,
[Account_Type] [varchar](22) NULL,
[Login_Name] [varchar](80) NULL,
[Def_DB] [varchar](100) NULL
) ON [PRIMARY]
INSERT INTO [tempdb].[dbo].[SQL_DB_REP]
EXEC sp_MSforeachdb 'SELECT CONVERT(varchar(100), SERVERPROPERTY(''Servername'')) AS Server,
''?'' AS DB_Name,
usu.name u_name,
CASE WHEN (usg.uid is null) THEN ''public''
ELSE usg.name END as Group_Name,
CASE WHEN usu.isntuser=1 THEN ''Windows Domain Account''
WHEN usu.isntgroup = 1 THEN ''Windows Group''
WHEN usu.issqluser = 1 THEN''SQL Account''
WHEN usu.issqlrole = 1 THEN ''SQL Role'' END as Account_Type,
lo.loginname,
lo.dbname AS Def_DB
FROM [?]..sysusers usu
LEFT OUTER JOIN([?]..sysmembers mem
INNER JOIN [?]..sysusers usg ON mem.groupuid = usg.uid) ON usu.uid = mem.memberuid
LEFT OUTER JOIN master.dbo.syslogins lo ON usu.sid = lo.sid
WHERE ( usu.islogin = 1
AND usu.isaliased = 0
AND usu.hasdbaccess = 1)
AND (usg.issqlrole = 1
OR usg.uid is null)'
SELECT * FROM [tempdb].[dbo].[SQL_DB_REP] ORDER BY [DB_Name]
DROP TABLE [tempdb].[dbo].[SQL_DB_REP]
END
GO
/****** Object: StoredProcedure [dbo].[utility_BASIC_GetServerBasicInfo] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get database server basic info
-- =============================================
CREATE PROCEDURE [dbo].[utility_BASIC_GetServerBasicInfo]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT CONVERT(CHAR(100), SERVERPROPERTY('Servername')) AS Server,
CONVERT(CHAR(100), SERVERPROPERTY('ProductVersion')) AS ProductVersion,
CONVERT(CHAR(100), SERVERPROPERTY('ProductLevel')) AS ProductLevel,
CONVERT(CHAR(100), SERVERPROPERTY('ResourceLastUpdateDateTime')) AS ResourceLastUpdateDateTime,
CONVERT(CHAR(100), SERVERPROPERTY('ResourceVersion')) AS ResourceVersion,
CASE WHEN SERVERPROPERTY('IsIntegratedSecurityOnly') = 1
THEN 'Integrated security'
WHEN SERVERPROPERTY('IsIntegratedSecurityOnly') = 0
THEN 'Not Integrated security'
END AS IsIntegratedSecurityOnly,
CASE WHEN SERVERPROPERTY('EngineEdition') = 1 THEN 'Personal Edition'
WHEN SERVERPROPERTY('EngineEdition') = 2 THEN 'Standard Edition'
WHEN SERVERPROPERTY('EngineEdition') = 3
THEN 'Enterprise Edition'
WHEN SERVERPROPERTY('EngineEdition') = 4 THEN 'Express Edition'
END AS EngineEdition,
CONVERT(CHAR(100), SERVERPROPERTY('InstanceName')) AS InstanceName,
CONVERT(CHAR(100), SERVERPROPERTY('ComputerNamePhysicalNetBIOS')) AS ComputerNamePhysicalNetBIOS,
CONVERT(CHAR(100), SERVERPROPERTY('LicenseType')) AS LicenseType,
CONVERT(CHAR(100), SERVERPROPERTY('NumLicenses')) AS NumLicenses,
CONVERT(CHAR(100), SERVERPROPERTY('BuildClrVersion')) AS BuildClrVersion,
CONVERT(CHAR(100), SERVERPROPERTY('Collation')) AS Collation,
CONVERT(CHAR(100), SERVERPROPERTY('CollationID')) AS CollationID,
CONVERT(CHAR(100), SERVERPROPERTY('ComparisonStyle')) AS ComparisonStyle,
CASE WHEN CONVERT(CHAR(100), SERVERPROPERTY('EditionID')) = -1253826760
THEN 'Desktop Edition'
WHEN SERVERPROPERTY('EditionID') = -1592396055
THEN 'Express Edition'
WHEN SERVERPROPERTY('EditionID') = -1534726760
THEN 'Standard Edition'
WHEN SERVERPROPERTY('EditionID') = 1333529388
THEN 'Workgroup Edition'
WHEN SERVERPROPERTY('EditionID') = 1804890536
THEN 'Enterprise Edition'
WHEN SERVERPROPERTY('EditionID') = -323382091
THEN 'Personal Edition'
WHEN SERVERPROPERTY('EditionID') = -2117995310
THEN 'Developer Edition'
WHEN SERVERPROPERTY('EditionID') = 610778273
THEN 'Enterprise Evaluation Edition'
WHEN SERVERPROPERTY('EditionID') = 1044790755
THEN 'Windows Embedded SQL'
WHEN SERVERPROPERTY('EditionID') = 4161255391
THEN 'Express Edition with Advanced Services'
END AS ProductEdition,
CASE WHEN CONVERT(CHAR(100), SERVERPROPERTY('IsClustered')) = 1
THEN 'Clustered'
WHEN SERVERPROPERTY('IsClustered') = 0 THEN 'Not Clustered'
WHEN SERVERPROPERTY('IsClustered') = NULL THEN 'Error'
END AS IsClustered,
CASE WHEN CONVERT(CHAR(100), SERVERPROPERTY('IsFullTextInstalled')) = 1
THEN 'Full-text is installed'
WHEN SERVERPROPERTY('IsFullTextInstalled') = 0
THEN 'Full-text is not installed'
WHEN SERVERPROPERTY('IsFullTextInstalled') = NULL THEN 'Error'
END AS IsFullTextInstalled,
CONVERT(CHAR(100), SERVERPROPERTY('SqlCharSet')) AS SqlCharSet,
CONVERT(CHAR(100), SERVERPROPERTY('SqlCharSetName')) AS SqlCharSetName,
CONVERT(CHAR(100), SERVERPROPERTY('SqlSortOrder')) AS SqlSortOrderID,
CONVERT(CHAR(100), SERVERPROPERTY('SqlSortOrderName')) AS SqlSortOrderName
ORDER BY CONVERT(CHAR(100), SERVERPROPERTY('Servername'))
END
GO
/****** Object: StoredProcedure [dbo].[utility_BASIC_ServiceCredentialBasicInfo] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get service credential basic info
-- =============================================
CREATE PROCEDURE [dbo].[utility_BASIC_ServiceCredentialBasicInfo]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
IF @@microsoftversion / power(2, 24) >= 9
BEGIN
EXEC sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE WITH OVERRIDE
END
IF EXISTS ( SELECT Name
FROM tempdb..sysobjects
WHERE name LIKE '#MyTempTable%')
DROP TABLE #MyTempTable
CREATE TABLE #MyTempTable
(
Big_String nvarchar(500)
)
INSERT INTO #MyTempTable
EXEC master..xp_cmdshell 'WMIC SERVICE GET Name,StartName | findstr /I SQL'
-- show service accounts
SELECT @@ServerName AS ServerName,
RTRIM(Left(Big_String, CHARINDEX(' ', Big_String))) AS ServiceName,
RTRIM(LTRIM(RTRIM(SUBSTRING(Big_String, CHARINDEX(' ', Big_String),LEN(Big_String))))) AS ServiceAccount
FROM #MyTempTable
IF @@microsoftversion / power(2, 24) >= 9
BEGIN
EXEC sp_configure 'xp_cmdshell', 0
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'show advanced options', 0
RECONFIGURE WITH OVERRIDE
END
END
GO
/****** Object: StoredProcedure [dbo].[utility_BLOCK_GetLockingInfoForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get locking information for all active processes, that is
--processes that have a running request, is holding locks or have an
--open transaction. Information about all locked objects are included,
--as well the last command sent from the client and the currently
--running statement. The procedure also displays the blocking chain
--for blocked processes.
-- =============================================
-- And here comes the procedure itself!
CREATE PROCEDURE [dbo].[utility_BLOCK_GetLockingInfoForAllDatabase] @allprocesses bit = 0,
@textmode bit = 0,
@procdata char(1) = NULL,
@debug bit = 0 AS
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
-- This table holds the information in sys.dm_tran_locks, aggregated
-- on a number of items. Note that we do not include subthreads or
-- requests in the aggregation. The IDENTITY column is there, because
-- we don't want character data in the clustered index.
DECLARE @locks TABLE (
database_id int NOT NULL,
entity_id bigint NULL,
session_id int NOT NULL,
req_mode varchar(60) COLLATE Latin1_General_BIN2 NOT NULL,
rsc_type varchar(60) COLLATE Latin1_General_BIN2 NOT NULL,
rsc_subtype varchar(60) COLLATE Latin1_General_BIN2 NOT NULL,
req_status varchar(60) COLLATE Latin1_General_BIN2 NOT NULL,
req_owner_type varchar(60) COLLATE Latin1_General_BIN2 NOT NULL,
rsc_description nvarchar(256) COLLATE Latin1_General_BIN2 NULL,
min_entity_id bigint NULL,
ismultipletemp bit NOT NULL DEFAULT 0,
cnt int NOT NULL,
activelock AS CASE WHEN rsc_type = 'DATABASE' AND
req_status = 'GRANT'
THEN convert(bit, 0)
ELSE convert(bit, 1)
END,
ident int IDENTITY,
rowno int NULL -- Set per session_id if @procdata is F.
UNIQUE CLUSTERED (database_id, entity_id, session_id, ident)
)
-- This table holds the translation of entity_id in @locks. This is a
-- temp table since we access it from dynamic SQL. The type_desc is used
-- for allocation units. The columns session_id, min_id and cnt are used
-- when consolidating temp tables.
CREATE TABLE #objects (
idtype char(4) NOT NULL
CHECK (idtype IN ('OBJ', 'HOBT', 'AU', 'MISC')),
database_id int NOT NULL,
entity_id bigint NOT NULL,
hobt_id bigint NULL,
object_name nvarchar(550) COLLATE Latin1_General_BIN2 NULL,
type_desc varchar(60) COLLATE Latin1_General_BIN2 NULL,
session_id smallint NULL,
min_id bigint NOT NULL,
cnt int NOT NULL DEFAULT 1
PRIMARY KEY CLUSTERED (database_id, idtype, entity_id),
UNIQUE NONCLUSTERED (database_id, entity_id, idtype),
CHECK (NOT (session_id IS NOT NULL AND database_id <> 2))
)
-- This table captures sys.dm_os_waiting_tasks and later augment it with
-- data about the block chain. A waiting task always has a always has a
-- task address, but the blocker may be idle and without a task.
-- All columns for the blocker are nullable, as we add extra rows for
-- non-waiting blockers.
DECLARE @dm_os_waiting_tasks TABLE
(wait_session_id smallint NOT NULL,
wait_task varbinary(8) NOT NULL,
block_session_id smallint NULL,
block_task varbinary(8) NULL,
wait_type varchar(60) COLLATE Latin1_General_BIN2 NULL,
wait_duration_ms bigint NULL,
-- The level in the chain. Level 0 is the lead blocker. NULL for
-- tasks that are waiting, but not blocking.
block_level smallint NULL,
-- The lead blocker for this block chain.
lead_blocker_spid smallint NULL,
-- Whether the block chain consists of the threads of the same spid only.
blocksamespidonly bit NOT NULL DEFAULT 0,
UNIQUE CLUSTERED (wait_session_id, wait_task, block_session_id, block_task),
UNIQUE (block_session_id, block_task, wait_session_id, wait_task)
)
-- This table holds information about transactions tied to a session.
-- A session can have multiple transactions when there are multiple
-- requests, but in that case we only save data about the oldest
-- transaction.
DECLARE @transactions TABLE (
session_id smallint NOT NULL,
is_user_trans bit NOT NULL,
trans_start datetime NOT NULL,
trans_since decimal(10,3) NULL,
trans_type int NOT NULL,
trans_state int NOT NULL,
dtc_state int NOT NULL,
is_bound bit NOT NULL,
PRIMARY KEY (session_id)
)
-- This table holds information about all sessions and requests.
DECLARE @procs TABLE (
session_id smallint NOT NULL,
task_address varbinary(8) NOT NULL,
exec_context_id int NOT NULL,
request_id int NOT NULL,
spidstr AS ltrim(str(session_id)) +
CASE WHEN exec_context_id <> 0 OR request_id <> 0
THEN '/' + ltrim(str(exec_context_id)) +
'/' + ltrim(str(request_id))
ELSE ''
END,
is_user_process bit NOT NULL,
orig_login nvarchar(128) COLLATE Latin1_General_BIN2 NULL,
current_login nvarchar(128) COLLATE Latin1_General_BIN2 NULL,
session_state varchar(30) COLLATE Latin1_General_BIN2 NOT NULL,
task_state varchar(60) COLLATE Latin1_General_BIN2 NULL,
proc_dbid smallint NULL,
request_dbid smallint NULL,
host_name nvarchar(128) COLLATE Latin1_General_BIN2 NULL,
host_process_id int NULL,
endpoint_id int NOT NULL,
program_name nvarchar(128) COLLATE Latin1_General_BIN2 NULL,
request_command varchar(32) COLLATE Latin1_General_BIN2 NULL,
trancount int NOT NULL,
session_cpu int NOT NULL,
request_cpu int NULL,
session_physio bigint NOT NULL,
request_physio bigint NULL,
session_logreads bigint NOT NULL,
request_logreads bigint NULL,
session_tempdb bigint NULL,
request_tempdb bigint NULL,
isclr bit NOT NULL DEFAULT 0,
nest_level int NULL,
now datetime NOT NULL,
login_time datetime NOT NULL,
last_batch datetime NOT NULL,
last_since decimal(10,3) NULL,
curdbid smallint NULL,
curobjid int NULL,
current_stmt nvarchar(MAX) COLLATE Latin1_General_BIN2 NULL,
sql_handle varbinary(64) NULL,
plan_handle varbinary(64) NULL,
stmt_start int NULL,
stmt_end int NULL,
current_plan xml NULL,
rowno int NOT NULL,
block_level tinyint NULL,
block_session_id smallint NULL,
block_exec_context_id int NULL,
block_request_id int NULL,
blockercnt int NULL,
block_spidstr AS ltrim(str(block_session_id)) +
CASE WHEN block_exec_context_id <> 0 OR block_request_id <> 0
THEN '/' + ltrim(str(block_exec_context_id)) +
'/' + ltrim(str(block_request_id))
ELSE ''
END +
CASE WHEN blockercnt > 1
THEN ' (+' + ltrim(str(blockercnt - 1)) + ')'
ELSE ''
END,
blocksamespidonly bit NOT NULL DEFAULT 0,
waiter_no_blocker bit NOT NULL DEFAULT 0,
wait_type varchar(60) COLLATE Latin1_General_BIN2 NULL,
wait_time decimal(18,3) NULL,
PRIMARY KEY (session_id, task_address))
-- Output from DBCC INPUTBUFFER. The IDENTITY column is there to make
-- it possible to add the spid later.
DECLARE @inputbuffer TABLE
(eventtype nvarchar(30) NULL,
params int NULL,
inputbuffer nvarchar(4000) NULL,
ident int IDENTITY UNIQUE,
spid int NOT NULL DEFAULT 0 PRIMARY KEY)
------------------------------------------------------------------------
-- Local variables.
------------------------------------------------------------------------
DECLARE @now datetime,
@ms int,
@spid smallint,
@rowc int,
@lvl int,
@dbname sysname,
@dbidstr varchar(10),
@objnameexpr nvarchar(MAX),
@stmt nvarchar(MAX),
@request_id int,
@handle varbinary(64),
@stmt_start int,
@stmt_end int;
------------------------------------------------------------------------
-- Set up.
------------------------------------------------------------------------
-- All reads are dirty! The most important reason for this is tempdb.sys.objects.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET NOCOUNT ON;
SELECT @now = getdate();
-- Validate the @procdata parameter, and set default.
IF @procdata IS NULL
SELECT @procdata = CASE @textmode WHEN 1 THEN 'A' ELSE 'F' END
IF @procdata NOT IN ('A', 'F')
BEGIN
RAISERROR('Invalid value for @procdata parameter. A and F are permitted', 16, 1)
RETURN
END
-- Check that user has permissions enough.
IF NOT EXISTS (SELECT *
FROM sys.fn_my_permissions(NULL, NULL)
WHERE permission_name = 'VIEW SERVER STATE')
BEGIN
RAISERROR('You need to have the permission VIEW SERVER STATE to run this procedure', 16, 1)
RETURN
END
-- If there is a request for textdata output, jump to the end where we call
-- ourselves non-texmode. (Ugly? Yes, having two procedures would be
-- prettier, but it's easier only have to distribute one.)
IF @textmode = 1 GOTO do_textmode
------------------------------------------------------------------------
-- First capture all locks. We aggregate by type, object etc to keep
-- down the volume.
------------------------------------------------------------------------
IF @debug = 1
BEGIN
RAISERROR ('Compiling lock information, time 0 ms.', 0, 1) WITH NOWAIT
END;
-- We force binary collation, to make the GROUP BY operation faster.
WITH CTE AS (
SELECT request_session_id,
req_mode = request_mode COLLATE Latin1_General_BIN2,
rsc_type = resource_type COLLATE Latin1_General_BIN2,
rsc_subtype = resource_subtype COLLATE Latin1_General_BIN2,
req_status = request_status COLLATE Latin1_General_BIN2,
req_owner_type = request_owner_type COLLATE Latin1_General_BIN2,
rsc_description =
CASE WHEN resource_type = 'APPLICATION'
THEN nullif(resource_description
COLLATE Latin1_General_BIN2, '')
END,
resource_database_id, resource_associated_entity_id
FROM sys.dm_tran_locks)
INSERT @locks (session_id, req_mode, rsc_type, rsc_subtype, req_status,
req_owner_type, rsc_description,
database_id, entity_id,
min_entity_id, cnt)
SELECT request_session_id, req_mode, rsc_type, rsc_subtype, req_status,
req_owner_type, rsc_description,
resource_database_id, resource_associated_entity_id,
resource_associated_entity_id, COUNT(*)
FROM CTE
GROUP BY request_session_id, req_mode, rsc_type, rsc_subtype, req_status,
req_owner_type, rsc_description,
resource_database_id, resource_associated_entity_id
-----------------------------------------------------------------------
-- Get the blocking chain.
-----------------------------------------------------------------------
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Determining blocking chain, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
-- First capture sys.dm_os_waiting_tasks, skipping non-spid tasks. The
-- DISTINCT is needed, because there may be duplicates. (I've seen them.)
INSERT @dm_os_waiting_tasks (wait_session_id, wait_task, block_session_id,
block_task, wait_type, wait_duration_ms)
SELECT DISTINCT
owt.session_id, owt.waiting_task_address, owt.blocking_session_id,
CASE WHEN owt.blocking_session_id IS NOT NULL
THEN coalesce(owt.blocking_task_address, 0x)
END, owt.wait_type, owt.wait_duration_ms
FROM sys.dm_os_waiting_tasks owt
WHERE owt.session_id IS NOT NULL;
-----------------------------------------------------------------------
-- Get transaction.
-----------------------------------------------------------------------
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Determining active transactions, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
; WITH oldest_tran AS (
SELECT tst.session_id, tst.is_user_transaction,
tat.transaction_begin_time, tat.transaction_type,
tat.transaction_state, tat.dtc_state, tst.is_bound,
rowno = row_number() OVER (PARTITION BY tst.session_id
ORDER BY tat.transaction_begin_time ASC)
FROM sys.dm_tran_session_transactions tst
JOIN sys.dm_tran_active_transactions tat
ON tst.transaction_id = tat.transaction_id
)
INSERT @transactions(session_id, is_user_trans, trans_start,
trans_since,
trans_type, trans_state, dtc_state, is_bound)
SELECT session_id, is_user_transaction, transaction_begin_time,
CASE WHEN datediff(DAY, transaction_begin_time, @now) > 20
THEN NULL
ELSE datediff(MS, transaction_begin_time, @now) / 1000.000
END,
transaction_type, transaction_state, dtc_state, is_bound
FROM oldest_tran
WHERE rowno = 1
------------------------------------------------------------------------
-- Then get the processes. We filter here for active processes once for all
------------------------------------------------------------------------
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Collecting process information, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
INSERT @procs(session_id, task_address,
exec_context_id, request_id,
is_user_process,
current_login,
orig_login,
session_state, task_state, endpoint_id, proc_dbid, request_dbid,
host_name, host_process_id, program_name, request_command,
trancount,
session_cpu, request_cpu,
session_physio, request_physio,
session_logreads, request_logreads,
session_tempdb, request_tempdb,
isclr, nest_level,
now, login_time, last_batch,
last_since,
sql_handle, plan_handle,
stmt_start, stmt_end,
rowno)
SELECT es.session_id, coalesce(ot.task_address, 0x),
coalesce(ot.exec_context_id, 0), coalesce(er.request_id, 0),
es.is_user_process,
coalesce(nullif(es.login_name, ''), suser_sname(es.security_id)),
coalesce(nullif(es.original_login_name, ''),
suser_sname(es.original_security_id)),
es.status, ot.task_state, es.endpoint_id, sp.dbid, er.database_id,
es.host_name, es.host_process_id, es.program_name, er.command,
coalesce(er.open_transaction_count, sp.open_tran),
es.cpu_time, er.cpu_time,
es.reads + es.writes, er.reads + er.writes,
es.logical_reads, er.logical_reads,
ssu.user_objects_alloc_page_count - ssu.user_objects_dealloc_page_count +
ssu.internal_objects_alloc_page_count - ssu.internal_objects_dealloc_page_count,
tsu.pages,
coalesce(er.executing_managed_code, 0), er.nest_level,
@now, es.login_time, es.last_request_start_time,
CASE WHEN datediff(DAY, es.last_request_start_time, @now) > 20
THEN NULL
ELSE datediff(MS, es.last_request_start_time, @now) / 1000.000
END,
er.sql_handle, er.plan_handle,
er.statement_start_offset, er.statement_end_offset,
rowno = row_number() OVER (PARTITION BY es.session_id
ORDER BY ot.exec_context_id, er.request_id)
FROM sys.dm_exec_sessions es
JOIN (SELECT spid, dbid = MIN(dbid), open_tran = MIN(open_tran)
FROM sys.sysprocesses
WHERE ecid = 0
GROUP BY spid) AS sp ON sp.spid = es.session_id
LEFT JOIN sys.dm_os_tasks ot ON es.session_id = ot.session_id
LEFT JOIN sys.dm_exec_requests er ON ot.task_address = er.task_address
LEFT JOIN sys.dm_db_session_space_usage ssu ON es.session_id = ssu.session_id
LEFT JOIN (SELECT session_id, request_id,
SUM(user_objects_alloc_page_count -
user_objects_dealloc_page_count +
internal_objects_alloc_page_count -
internal_objects_dealloc_page_count) AS pages
FROM sys.dm_db_task_space_usage
WHERE database_id = 2
GROUP BY session_id, request_id) AS tsu ON tsu.session_id = er.session_id
AND tsu.request_id = er.request_id
WHERE -- All processes requested
@allprocesses > 0
-- All user sessions with a running request save ourselevs.
OR ot.exec_context_id IS NOT NULL AND
es.is_user_process = 1 AND
es.session_id <> @@spid
-- All sessions with an open transaction, even if they are idle.
OR sp.open_tran > 0 AND es.session_id <> @@spid
-- All sessions that have an interesting lock, save ourselves.
OR EXISTS (SELECT *
FROM @locks l
WHERE l.session_id = es.session_id
AND l.activelock = 1) AND es.session_id <> @@spid
-- All sessions that is blocking someone.
OR EXISTS (SELECT *
FROM @dm_os_waiting_tasks owt
WHERE owt.block_session_id = es.session_id)
OR ssu.user_objects_alloc_page_count - ssu.user_objects_dealloc_page_count +
ssu.internal_objects_alloc_page_count - ssu.internal_objects_dealloc_page_count > 1000
------------------------------------------------------------------------
-- Get input buffers. Note that we can only find one per session, even
-- a session has several requests.
-- We skip this part if @@nestlevel is > 1, as presumably we are calling
-- ourselves recursively from INSERT EXEC, and we may no not do another
-- level of INSERT-EXEC.
------------------------------------------------------------------------
IF @@nestlevel = 1
BEGIN
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Getting input buffers, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
DECLARE C1 CURSOR FAST_FORWARD LOCAL FOR
SELECT DISTINCT session_id
FROM @procs
WHERE is_user_process = 1
OPEN C1
WHILE 1 = 1
BEGIN
FETCH C1 INTO @spid
IF @@fetch_status <> 0
BREAK
BEGIN TRY
INSERT @inputbuffer(eventtype, params, inputbuffer)
EXEC sp_executesql N'DBCC INPUTBUFFER (@spid) WITH NO_INFOMSGS',
N'@spid int', @spid
UPDATE @inputbuffer
SET spid = @spid
WHERE ident = scope_identity()
END TRY
BEGIN CATCH
INSERT @inputbuffer(inputbuffer, spid)
VALUES('Error getting inputbuffer: ' + error_message(), @spid)
END CATCH
END
DEALLOCATE C1
END
-----------------------------------------------------------------------
-- Compute the blocking chain.
-----------------------------------------------------------------------
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Computing blocking chain, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
-- Mark blockers that are waiting, that is waiting for something else
-- than another spid.
UPDATE @dm_os_waiting_tasks
SET block_level = 0,
lead_blocker_spid = a.wait_session_id
FROM @dm_os_waiting_tasks a
WHERE a.block_session_id IS NULL
AND EXISTS (SELECT *
FROM @dm_os_waiting_tasks b
WHERE a.wait_session_id = b.block_session_id
AND a.wait_task = b.block_task)
SELECT @rowc = @@rowcount
-- Add an extra row for blockers that are not waiting at all.
INSERT @dm_os_waiting_tasks (wait_session_id, wait_task,
block_level, lead_blocker_spid)
SELECT DISTINCT a.block_session_id, coalesce(a.block_task, 0x),
0, a.block_session_id
FROM @dm_os_waiting_tasks a
WHERE NOT EXISTS (SELECT *
FROM @dm_os_waiting_tasks b
WHERE a.block_session_id = b.wait_session_id
AND a.block_task = b.wait_task)
AND a.block_session_id IS NOT NULL;
SELECT @rowc = @rowc + @@rowcount, @lvl = 0
-- Then iterate as long as we find blocked processes. You may think
-- that a recursive CTE would be great here, but we want to exclude
-- rows that has already been marked. This is difficult to do with a CTE.
WHILE @rowc > 0
BEGIN
UPDATE a
SET block_level = b.block_level + 1,
lead_blocker_spid = b.lead_blocker_spid
FROM @dm_os_waiting_tasks a
JOIN @dm_os_waiting_tasks b ON a.block_session_id = b.wait_session_id
AND a.block_task = b.wait_task
WHERE b.block_level = @lvl
AND a.block_level IS NULL
SELECT @rowc = @@rowcount, @lvl = @lvl + 1
END
-- Next to find are processes that are blocked, but no one is waiting for.
-- They are directly or indirectly blocked by a deadlock. They get a
-- negative level initially. We clean this up later.
UPDATE @dm_os_waiting_tasks
SET block_level = -1
FROM @dm_os_waiting_tasks a
WHERE a.block_level IS NULL
AND a.block_session_id IS NOT NULL
AND NOT EXISTS (SELECT *
FROM @dm_os_waiting_tasks b
WHERE b.block_session_id = a.wait_session_id
AND b.block_task = a.wait_task)
SELECT @rowc = @@rowcount, @lvl = -2
-- Then unwind these chains in the opposite direction to before.
WHILE @rowc > 0
BEGIN
UPDATE @dm_os_waiting_tasks
SET block_level = @lvl
FROM @dm_os_waiting_tasks a
WHERE a.block_level IS NULL
AND a.block_session_id IS NOT NULL
AND NOT EXISTS (SELECT *
FROM @dm_os_waiting_tasks b
WHERE b.block_session_id = a.wait_session_id
AND b.block_task = a.wait_task
AND b.block_level IS NULL)
SELECT @rowc = @@rowcount, @lvl = @lvl - 1
END
-- Determine which blocking tasks that only block tasks within the same
-- spid.
UPDATE @dm_os_waiting_tasks
SET blocksamespidonly = 1
FROM @dm_os_waiting_tasks a
WHERE a.block_level IS NOT NULL
AND a.wait_session_id = a.lead_blocker_spid
AND NOT EXISTS (SELECT *
FROM @dm_os_waiting_tasks b
WHERE a.wait_session_id = b.lead_blocker_spid
AND a.wait_session_id <> b.wait_session_id)
-----------------------------------------------------------------------
-- Add block-chain and wait information to @procs. If a blockee has more
-- than one blocker, we pick one.
-----------------------------------------------------------------------
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Adding blocking chain to @procs, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
; WITH block_chain AS (
SELECT wait_session_id, wait_task, block_session_id, block_task,
block_level = CASE WHEN block_level >= 0 THEN block_level
ELSE block_level - @lvl - 1
END,
wait_duration_ms, wait_type, blocksamespidonly,
cnt = COUNT(*) OVER (PARTITION BY wait_task),
rowno = row_number() OVER (PARTITION BY wait_task
ORDER BY block_level, block_task)
FROM @dm_os_waiting_tasks
)
UPDATE p
SET block_level = bc.block_level,
block_session_id = bc.block_session_id,
block_exec_context_id = coalesce(p2.exec_context_id, -1),
block_request_id = coalesce(p2.request_id, -1),
blockercnt = bc.cnt,
blocksamespidonly = bc.blocksamespidonly,
wait_time = convert(decimal(18, 3), bc.wait_duration_ms) / 1000,
wait_type = bc.wait_type
FROM @procs p
JOIN block_chain bc ON p.session_id = bc.wait_session_id
AND p.task_address = bc.wait_task
AND bc.rowno = 1
LEFT JOIN @procs p2 ON bc.block_session_id = p2.session_id
AND bc.block_task = p2.task_address
--------------------------------------------------------------------
-- Delete "uninteresting" locks from @locks for processes not in @procs.
--------------------------------------------------------------------
IF @allprocesses = 0
BEGIN
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Deleting uninteresting locks, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
DELETE @locks
FROM @locks l
WHERE (activelock = 0 OR session_id = @@spid)
AND NOT EXISTS (SELECT *
FROM @procs p
WHERE p.session_id = l.session_id)
END
----------------------------------------------------------------------
-- Get the query text. This is not done in the main query, as we could
-- be blocked if someone is creating an SP and executes it in a
-- transaction.
----------------------------------------------------------------------
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Retrieving current statement, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
-- Set lock timeout to avoid being blocked.
SET LOCK_TIMEOUT 5
-- First try to get all query plans in one go.
BEGIN TRY
UPDATE @procs
SET curdbid = est.dbid,
curobjid = est.objectid,
current_stmt =
CASE WHEN est.encrypted = 1
THEN '-- ENCRYPTED, pos ' +
ltrim(str((p.stmt_start + 2)/2)) + ' - ' +
ltrim(str((p.stmt_end + 2)/2))
WHEN p.stmt_start >= 0
THEN substring(est.text, (p.stmt_start + 2)/2,
CASE p.stmt_end
WHEN -1 THEN datalength(est.text)
ELSE (p.stmt_end - p.stmt_start + 2) / 2
END)
END
FROM @procs p
CROSS APPLY sys.dm_exec_sql_text(p.sql_handle) est
END TRY
BEGIN CATCH
-- If this fails, try to get the texts one by one.
DECLARE text_cur CURSOR STATIC LOCAL FOR
SELECT DISTINCT session_id, request_id, sql_handle,
stmt_start, stmt_end
FROM @procs
WHERE sql_handle IS NOT NULL
OPEN text_cur
WHILE 1 = 1
BEGIN
FETCH text_cur INTO @spid, @request_id, @handle,
@stmt_start, @stmt_end
IF @@fetch_status <> 0
BREAK
BEGIN TRY
UPDATE @procs
SET curdbid = est.dbid,
curobjid = est.objectid,
current_stmt =
CASE WHEN est.encrypted = 1
THEN '-- ENCRYPTED, pos ' +
ltrim(str((p.stmt_start + 2)/2)) + ' - ' +
ltrim(str((p.stmt_end + 2)/2))
WHEN p.stmt_start >= 0
THEN substring(est.text, (p.stmt_start + 2)/2,
CASE p.stmt_end
WHEN -1 THEN datalength(est.text)
ELSE (p.stmt_end - p.stmt_start + 2) / 2
END)
END
FROM @procs p
CROSS APPLY sys.dm_exec_sql_text(p.sql_handle) est
WHERE p.session_id = @spid
AND p.request_id = @request_id
END TRY
BEGIN CATCH
UPDATE @procs
SET current_stmt = 'ERROR: *** ' + error_message() + ' ***'
WHERE session_id = @spid
AND request_id = @request_id
END CATCH
END
DEALLOCATE text_cur
END CATCH
SET LOCK_TIMEOUT 0
-----------------------------------------------------------------------
-- Get object names from ids in @procs and @locks. You may think that
-- we could use object_name and its second database parameter, but
-- object_name takes out a Sch-S lock (even with READ UNCOMMITTED) and
-- gets blocked if a object (read temp table) has been created in a transaction.
-----------------------------------------------------------------------
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Getting object names, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
-- First get all entity ids into the temp table. And yes, do save them in
-- three columns. We translate the resource types to our own type, depending
-- on names are to be looked up. The session_id is only of interest in
-- tempdb and only for temp tables. We use MIN, since is the same data
-- appears for the same session_id, it cannot be a temp table.
INSERT #objects (idtype, database_id, entity_id, hobt_id, min_id, session_id)
SELECT idtype, database_id, entity_id, entity_id, entity_id,
MIN(session_id)
FROM (SELECT CASE WHEN rsc_type = 'OBJECT' THEN 'OBJ'
WHEN rsc_type IN ('PAGE', 'KEY', 'RID', 'HOBT') THEN 'HOBT'
WHEN rsc_type = 'ALLOCATION_UNIT' THEN 'AU'
END AS idtype,
database_id, entity_id,
CASE database_id WHEN 2 THEN session_id END AS session_id
FROM @locks) AS l
WHERE idtype IS NOT NULL
GROUP BY idtype, database_id, entity_id
UNION
SELECT DISTINCT 'OBJ', curdbid, curobjid, curobjid, curobjid, NULL
FROM @procs
WHERE curdbid IS NOT NULL
AND curobjid IS NOT NULL
-- If the user does not have CONTROL SERVER, he may not be able to access all
-- databases. In this case, we save this to the table directly, rather than
-- handling it the error handler below (because else it destroys textmode).
IF NOT EXISTS (SELECT *
FROM sys.fn_my_permissions(NULL, NULL)
WHERE permission_name = 'CONTROL SERVER')
BEGIN
UPDATE #objects
SET object_name = 'You do not have permissions to access the database ' +
quotename(db_name(database_id)) + '.'
WHERE has_dbaccess(db_name(database_id)) = 0
END
DECLARE C2 CURSOR STATIC LOCAL FOR
SELECT DISTINCT str(database_id),
quotename(db_name(database_id))
FROM #objects
WHERE idtype IN ('OBJ', 'HOBT', 'AU')
AND object_name IS NULL
OPTION (KEEPFIXED PLAN)
OPEN C2
WHILE 1 = 1
BEGIN
FETCH C2 INTO @dbidstr, @dbname
IF @@fetch_status <> 0
BREAK
-- This expression is used to for the object name. It looks differently
-- in tempdb where we drop the unique parts of temp-tables.
SELECT @objnameexpr =
CASE @dbname
WHEN '[tempdb]'
THEN 'CASE WHEN len(o.name) = 9 AND
o.name LIKE "#" + replicate("[0-9A-F]", 8)
THEN "#(tblvar or dropped temp table)"
WHEN len(o.name) = 128 AND o.name LIKE "#[^#]%"
THEN substring(o.name, 1, charindex("_____", o.name) - 1)
ELSE db_name(@dbidstr) + "." +
coalesce(s.name + "." + o.name,
"<" + ltrim(str(ob.entity_id)) + ">")
END'
ELSE 'db_name(@dbidstr) + "." +
coalesce(s.name + "." + o.name,
"<" + ltrim(str(ob.entity_id)) + ">")'
END
-- First handle allocation units. They bring us a hobt_id, or we go
-- directly to the object when the container is a partition_id. We
-- always get the type_desc. To make the dynamic SQL easier to read,
-- we use some placeholders.
SELECT @stmt = '
UPDATE #objects
SET type_desc = au.type_desc,
hobt_id = CASE WHEN au.type IN (1, 3)
THEN au.container_id
END,
idtype = CASE WHEN au.type IN (1, 3)
THEN "HOBT"
ELSE "AU"
END,
object_name = CASE WHEN au.type = 2 THEN ' +
@objnameexpr + ' +
CASE WHEN p.index_id <= 1
THEN ""
ELSE "." + i.name
END +
CASE WHEN p.partition_number > 1
THEN "(" +
ltrim(str(p.partition_number)) +
")"
ELSE ""
END
WHEN au.type = 0 THEN
db_name(@dbidstr) + " (dropped table et al)"
END
FROM #objects ob
JOIN @dbname.sys.allocation_units au ON ob.entity_id = au.allocation_unit_id
-- We should only go all the way from sys.partitions, for type = 3.
LEFT JOIN (@dbname.sys.partitions p
JOIN @dbname.sys.objects o ON p.object_id = o.object_id
JOIN @dbname.sys.indexes i ON p.object_id = i.object_id
AND p.index_id = i.index_id
JOIN @dbname.sys.schemas s ON o.schema_id = s.schema_id)
ON au.container_id = p.partition_id
AND au.type = 2
WHERE ob.database_id = @dbidstr
AND ob.idtype = "AU"
OPTION (KEEPFIXED PLAN);
'
-- Now we can translate all hobt_id, including those we got from the
-- allocation units.
SELECT @stmt = @stmt + '
UPDATE #objects
SET object_name = ' + @objnameexpr + ' +
CASE WHEN p.index_id <= 1
THEN ""
ELSE "." + i.name
END +
CASE WHEN p.partition_number > 1
THEN "(" +
ltrim(str(p.partition_number)) +
")"
ELSE ""
END + coalesce(" (" + ob.type_desc + ")", "")
FROM #objects ob
JOIN @dbname.sys.partitions p ON ob.hobt_id = p.hobt_id
JOIN @dbname.sys.objects o ON p.object_id = o.object_id
JOIN @dbname.sys.indexes i ON p.object_id = i.object_id
AND p.index_id = i.index_id
JOIN @dbname.sys.schemas s ON o.schema_id = s.schema_id
WHERE ob.database_id = @dbidstr
AND ob.idtype = "HOBT"
OPTION (KEEPFIXED PLAN)
'
-- And now object ids, idtype = OBJ.
SELECT @stmt = @stmt + '
UPDATE #objects
SET object_name = ' + @objnameexpr + '
FROM #objects ob
LEFT JOIN (@dbname.sys.objects o
JOIN @dbname.sys.schemas s ON o.schema_id = s.schema_id)
ON convert(int, ob.entity_id) = o.object_id
WHERE ob.database_id = @dbidstr
AND ob.idtype = "OBJ"
OPTION (KEEPFIXED PLAN)
'
-- When running beta_lockinfo with only VIEW SERVER STATE, without being
-- sysadmin, reading from the system tables will block on SQL 2005 and
-- SQL 2008. Address this.
SELECT @stmt = ' BEGIN TRY
SET LOCK_TIMEOUT 5
' + @stmt +
' END TRY
BEGIN CATCH
UPDATE #objects
SET object_name = "Error getting object name: " +
error_message()
WHERE database_id = @dbidstr
AND object_name IS NULL
END CATCH
'
-- Fix the placeholders.
SELECT @stmt = replace(replace(replace(@stmt,
'"', ''''),
'@dbname', @dbname),
'@dbidstr', @dbidstr)
-- And run the beast.
-- PRINT @stmt
EXEC (@stmt)
END
DEALLOCATE C2
-------------------------------------------------------------------
-- Consolidate temp tables, so that if a procedure has a lock on
-- several temp tables with the same name, it is only listed once.
-------------------------------------------------------------------
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Consolidating temp tables, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
-- Count the temp tables, and find the lowest id in each group.
; WITH mintemp AS (
SELECT object_name, session_id, idtype,
MIN(entity_id) AS min_id, COUNT(*) AS cnt
FROM #objects
WHERE database_id = 2
AND object_name LIKE '#[^#]%'
GROUP BY object_name, session_id, idtype
HAVING COUNT(*) > 1
)
UPDATE #objects
SET min_id = m.min_id,
cnt = m.cnt,
object_name = m.object_name + ' (x' + ltrim(str(m.cnt)) + ')'
FROM #objects o
JOIN mintemp m ON m.object_name = o.object_name
AND m.idtype = o.idtype
AND m.session_id = o.session_id
WHERE o.database_id = 2
OPTION (KEEPFIXED PLAN)
SELECT @rowc = @@rowcount
IF @rowc > 0
BEGIN
UPDATE @locks
SET min_entity_id = ob.min_id,
ismultipletemp = 1
FROM @locks l
JOIN #objects ob ON l.database_id = ob.database_id
AND l.entity_id = ob.entity_id
AND l.session_id = ob.session_id
WHERE l.database_id = 2
AND ob.database_id = 2
AND ob.cnt > 1
OPTION (KEEPFIXED PLAN)
INSERT @locks (session_id, req_mode, rsc_type, rsc_subtype, req_status,
req_owner_type, database_id, entity_id, cnt)
SELECT session_id, req_mode, rsc_type, rsc_subtype, req_status,
req_owner_type, 2, min_entity_id, SUM(cnt)
FROM @locks
WHERE database_id = 2
AND ismultipletemp = 1
GROUP BY session_id, req_mode, rsc_type, rsc_subtype, req_status,
req_owner_type, min_entity_id
END
--------------------------------------------------------------------
-- Get query plans. The difficult part is that the convert to xml may
-- fail if the plan is too deep. Therefore we catch this error, and
-- resort to a cursor in this case. Since query plans are not included
-- in text mode, we skip if @nestlevel is > 1.
--------------------------------------------------------------------
IF @@nestlevel = 1
BEGIN
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Retrieving query plans, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
-- Adam says that getting the query plans can time out too...
SET LOCK_TIMEOUT 5
BEGIN TRY
UPDATE @procs
SET current_plan = convert(xml, etqp.query_plan)
FROM @procs p
OUTER APPLY sys.dm_exec_text_query_plan(
p.plan_handle, p.stmt_start, p.stmt_end) etqp
WHERE p.plan_handle IS NOT NULL
END TRY
BEGIN CATCH
DECLARE plan_cur CURSOR STATIC LOCAL FOR
SELECT DISTINCT session_id, request_id, plan_handle,
stmt_start, stmt_end
FROM @procs
WHERE plan_handle IS NOT NULL
OPEN plan_cur
WHILE 1 = 1
BEGIN
FETCH plan_cur INTO @spid, @request_id, @handle,
@stmt_start, @stmt_end
IF @@fetch_status <> 0
BREAK
BEGIN TRY
UPDATE @procs
SET current_plan = (SELECT convert(xml, etqp.query_plan)
FROM sys.dm_exec_text_query_plan(
@handle, @stmt_start, @stmt_end) etqp)
FROM @procs p
WHERE p.session_id = @spid
AND p.request_id = @request_id
END TRY
BEGIN CATCH
UPDATE @procs
SET current_plan =
(SELECT 'Could not get query plan' AS [@alert],
error_number() AS [@errno],
error_severity() AS [@level],
error_message() AS [@errmsg]
FOR XML PATH('ERROR'))
WHERE session_id = @spid
AND request_id = @request_id
END CATCH
END
DEALLOCATE plan_cur
END CATCH
SET LOCK_TIMEOUT 0
-- There is a bug in dm_exec_text_query_plan which causes the attribute
-- StatementText to include the full text of the batch up to current
-- statement. This causes bloat in SSMS. Whence we fix the attribute.
; WITH XMLNAMESPACES(
'http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS SP)
UPDATE @procs
SET current_plan.modify('
replace value of (
/SP:ShowPlanXML/SP:BatchSequence/SP:Batch/
SP:Statements/SP:StmtSimple/@StatementText)[1]
with
substring((/SP:ShowPlanXML/SP:BatchSequence/SP:Batch/
SP:Statements/SP:StmtSimple/@StatementText)[1],
(sql:column("stmt_start") + 2) div 2)
')
WHERE current_plan IS NOT NULL
AND stmt_start IS NOT NULL
END
--------------------------------------------------------------------
-- If user has selected to see process data only on the first row,
-- we should number the rows in @locks.
--------------------------------------------------------------------
IF @procdata = 'F'
BEGIN
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Determining first row, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
; WITH locks_rowno AS (
SELECT rowno,
new_rowno = row_number() OVER(PARTITION BY l.session_id
ORDER BY CASE l.req_status
WHEN 'GRANT' THEN 'ZZZZ'
ELSE l.req_status
END,
o.object_name, l.rsc_type, l.rsc_description)
FROM @locks l
LEFT JOIN #objects o ON l.database_id = o.database_id
AND l.entity_id = o.entity_id)
UPDATE locks_rowno
SET rowno = new_rowno
OPTION (KEEPFIXED PLAN)
END
---------------------------------------------------------------------
-- Before we can join in the locks, we need to make sure that all
-- processes with a running request has a row with exec_context_id =
-- request_id = 0. (Those without already has such a row.)
---------------------------------------------------------------------
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Supplementing @procs, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
INSERT @procs(session_id, task_address, exec_context_id, request_id,
is_user_process, orig_login, current_login,
session_state, endpoint_id, trancount, proc_dbid,
host_name, host_process_id, program_name,
session_cpu, session_physio, session_logreads,
now, login_time, last_batch, last_since, rowno)
SELECT session_id, 0x, 0, 0,
is_user_process, orig_login, current_login,
session_state, endpoint_id, 0, proc_dbid,
host_name, host_process_id, program_name,
session_cpu, session_physio, session_logreads,
now, login_time, last_batch, last_since, 0
FROM @procs a
WHERE a.rowno = 1
AND NOT EXISTS (SELECT *
FROM @procs b
WHERE b.session_id = a.session_id
AND b.exec_context_id = 0
AND b.request_id = 0)
-- A process may be waiting for a lock according sys.dm_os_tran_locks,
-- but it was not in sys.dm_os_waiting_tasks. Let's mark this up.
UPDATE @procs
SET waiter_no_blocker = 1
FROM @procs p
WHERE EXISTS (SELECT *
FROM @locks l
WHERE l.req_status = 'WAIT'
AND l.session_id = p.session_id
AND NOT EXISTS (SELECT *
FROM @procs p2
WHERE p.session_id = l.session_id))
------------------------------------------------------------------------
-- For Plain results we are ready to return now.
------------------------------------------------------------------------
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Returning result set, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
IF @textmode = 0
BEGIN
-- Note that the query is a full join, since @locks and @procs may not
-- be in sync. Processes may have gone away, or be active without any
-- locks. As for the transactions, we team up with the processes.
SELECT spid = coalesce(p.spidstr, ltrim(str(l.session_id))),
command = CASE WHEN coalesce(p.exec_context_id, 0) = 0 AND
coalesce(l.rowno, 1) = 1
THEN p.request_command
ELSE ''
END,
login = CASE WHEN coalesce(p.exec_context_id, 0) = 0 AND
coalesce(l.rowno, 1) = 1
THEN
CASE WHEN p.is_user_process = 0
THEN 'SYSTEM PROCESS'
ELSE p.orig_login +
CASE WHEN p.current_login <> p.orig_login OR
p.orig_login IS NULL
THEN ' (' + p.current_login + ')'
ELSE ''
END
END
ELSE ''
END,
host = CASE WHEN coalesce(p.exec_context_id, 0)= 0 AND
coalesce(l.rowno, 1) = 1
THEN p.host_name
ELSE ''
END,
hostprc = CASE WHEN coalesce(p.exec_context_id, 0) = 0 AND
coalesce(l.rowno, 1) = 1
THEN ltrim(str(p.host_process_id))
ELSE ''
END,
endpoint = CASE WHEN coalesce(p.exec_context_id, 0) = 0 AND
coalesce(l.rowno, 1) = 1
THEN e.name
ELSE ''
END,
appl = CASE WHEN coalesce(p.exec_context_id, 0) = 0 AND
coalesce(l.rowno, 1) = 1
THEN p.program_name
ELSE ''
END,
dbname = CASE WHEN coalesce(l.rowno, 1) = 1 AND
coalesce(p.exec_context_id, 0) = 0
THEN coalesce(db_name(p.request_dbid),
db_name(p.proc_dbid))
ELSE ''
END,
prcstatus = CASE WHEN coalesce(l.rowno, 1) = 1
THEN coalesce(p.task_state, p.session_state)
ELSE ''
END,
spid_ = p.spidstr,
opntrn = CASE WHEN p.exec_context_id = 0
THEN coalesce(ltrim(str(nullif(p.trancount, 0))), '')
ELSE ''
END,
trninfo = CASE WHEN coalesce(l.rowno, 1) = 1 AND
p.exec_context_id = 0 AND
t.is_user_trans IS NOT NULL
THEN CASE t.is_user_trans
WHEN 1 THEN 'U'
ELSE 'S'
END + '-' +
CASE t.trans_type
WHEN 1 THEN 'RW'
WHEN 2 THEN 'R'
WHEN 3 THEN 'SYS'
WHEN 4 THEN 'DIST'
ELSE ltrim(str(t.trans_type))
END + '-' +
ltrim(str(t.trans_state)) +
CASE t.dtc_state
WHEN 0 THEN ''
ELSE '-'
END +
CASE t.dtc_state
WHEN 0 THEN ''
WHEN 1 THEN 'DTC:ACTIVE'
WHEN 2 THEN 'DTC:PREPARED'
WHEN 3 THEN 'DTC:COMMITED'
WHEN 4 THEN 'DTC:ABORTED'
WHEN 5 THEN 'DTC:RECOVERED'
ELSE 'DTC:' + ltrim(str(t.dtc_state))
END +
CASE t.is_bound
WHEN 0 THEN ''
WHEN 1 THEN '-BND'
END
ELSE ''
END,
blklvl = CASE WHEN p.block_level IS NOT NULL
THEN CASE p.blocksamespidonly
WHEN 1 THEN '('
ELSE ''
END +
CASE WHEN p.block_level = 0
THEN '!!'
ELSE ltrim(str(p.block_level))
END +
CASE p.blocksamespidonly
WHEN 1 THEN ')'
ELSE ''
END
-- If the process is blocked, but we do not
-- have a block level, the process is in a
-- dead lock.
WHEN p.block_session_id IS NOT NULL
THEN 'DD'
WHEN p.waiter_no_blocker = 1
THEN '??'
ELSE ''
END,
blkby = coalesce(p.block_spidstr, ''),
cnt = CASE WHEN p.exec_context_id = 0 AND
p.request_id = 0
THEN coalesce(ltrim(str(l.cnt)), '0')
ELSE ''
END,
object = CASE l.rsc_type
WHEN 'APPLICATION'
THEN coalesce(db_name(l.database_id) + '|', '') +
l.rsc_description
ELSE coalesce(o2.object_name,
db_name(l.database_id), '')
END,
rsctype = coalesce(l.rsc_type, ''),
locktype = coalesce(l.req_mode, ''),
lstatus = CASE l.req_status
WHEN 'GRANT' THEN lower(l.req_status)
ELSE coalesce(l.req_status, '')
END,
ownertype = CASE l.req_owner_type
WHEN 'SHARED_TRANSACTION_WORKSPACE' THEN 'STW'
ELSE coalesce(l.req_owner_type, '')
END,
rscsubtype = coalesce(l.rsc_subtype, ''),
waittime = CASE WHEN coalesce(l.rowno, 1) = 1
THEN coalesce(ltrim(str(p.wait_time, 18, 3)), '')
ELSE ''
END,
waittype = CASE WHEN coalesce(l.rowno, 1) = 1
THEN coalesce(p.wait_type, '')
ELSE ''
END,
spid__ = p.spidstr,
cpu = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1
THEN coalesce(ltrim(str(p.session_cpu)), '') +
CASE WHEN p.request_cpu IS NOT NULL
THEN ' (' + ltrim(str(p.request_cpu)) + ')'
ELSE ''
END
ELSE ''
END,
physio = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1
THEN coalesce(ltrim(str(p.session_physio, 18)), '') +
CASE WHEN p.request_physio IS NOT NULL
THEN ' (' + ltrim(str(p.request_physio)) + ')'
ELSE ''
END
ELSE ''
END,
logreads = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1
THEN coalesce(ltrim(str(p.session_logreads, 18)), '') +
CASE WHEN p.request_logreads IS NOT NULL
THEN ' (' + ltrim(str(p.request_logreads)) + ')'
ELSE ''
END
ELSE ''
END,
tempdb = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1
THEN coalesce(ltrim(str(p.session_tempdb, 18)), '') +
CASE WHEN p.request_tempdb IS NOT NULL
THEN ' (' + ltrim(str(p.request_tempdb)) + ')'
ELSE ''
END
ELSE ''
END,
now = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1
THEN convert(char(12), p.now, 114)
ELSE ''
END,
login_time = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1
THEN
CASE datediff(DAY, p.login_time, @now)
WHEN 0
THEN convert(varchar(8), p.login_time, 8)
ELSE convert(char(7), p.login_time, 12) +
convert(varchar(8), p.login_time, 8)
END
ELSE ''
END,
last_batch = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1
THEN
CASE datediff(DAY, p.last_batch, @now)
WHEN 0
THEN convert(varchar(8),
p.last_batch, 8)
ELSE convert(char(7), p.last_batch, 12) +
convert(varchar(8), p.last_batch, 8)
END
ELSE ''
END,
trn_start = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1 AND
t.trans_start IS NOT NULL
THEN
CASE datediff(DAY, t.trans_start, @now)
WHEN 0
THEN convert(varchar(8),
t.trans_start, 8)
ELSE convert(char(7), t.trans_start, 12) +
convert(varchar(8), t.trans_start, 8)
END
ELSE ''
END,
last_since = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1
THEN str(p.last_since, 11, 3)
ELSE ''
END,
trn_since = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1 AND
t.trans_since IS NOT NULL
THEN str(t.trans_since, 11, 3)
ELSE ''
END,
clr = CASE WHEN p.exec_context_id = 0 AND p.isclr = 1
THEN 'CLR'
ELSE ''
END,
nstlvl = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1
THEN coalesce(ltrim(str(p.nest_level)), '')
ELSE ''
END,
spid___ = p.spidstr,
inputbuffer = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1
THEN coalesce(i.inputbuffer, '')
ELSE ''
END,
current_sp = coalesce(o1.object_name, ''),
curstmt = CASE WHEN coalesce(l.rowno, 1) = 1
THEN coalesce(p.current_stmt, '')
ELSE coalesce(substring(
p.current_stmt, 1, 50), '')
END,
current_plan = CASE WHEN p.exec_context_id = 0 AND
coalesce(l.rowno, 1) = 1
THEN p.current_plan
END
FROM @procs p
LEFT JOIN #objects o1 ON p.curdbid = o1.database_id
AND p.curobjid = o1.entity_id
LEFT JOIN @inputbuffer i ON p.session_id = i.spid
AND p.exec_context_id = 0
LEFT JOIN sys.endpoints e ON p.endpoint_id = e.endpoint_id
LEFT JOIN @transactions t ON t.session_id = p.session_id
FULL JOIN ((SELECT *
FROM @locks
WHERE ismultipletemp = 0) AS l
LEFT JOIN #objects o2 ON l.database_id = o2.database_id
AND l.entity_id = o2.entity_id)
ON p.session_id = l.session_id
AND p.exec_context_id = 0
AND p.request_id = 0
ORDER BY coalesce(p.session_id, l.session_id),
p.exec_context_id, coalesce(nullif(p.request_id, 0), 99999999),
l.rowno, lstatus,
coalesce(o2.object_name, db_name(l.database_id)),
l.rsc_type, l.rsc_description
OPTION (KEEPFIXED PLAN)
END
ELSE
BEGIN
do_textmode:
------------------------------------------------------------------------
-- For textmode result, we run ourselves in gridmode, receiving the
-- result into a temp table.
------------------------------------------------------------------------
CREATE TABLE #textmode(
ident int IDENTITY,
spid varchar(30) COLLATE Latin1_General_BIN2 NOT NULL,
command varchar(32) COLLATE Latin1_General_BIN2 NULL,
login sysname COLLATE Latin1_General_BIN2 NULL,
host nvarchar(128) COLLATE Latin1_General_BIN2 NULL,
hostprc varchar(10) COLLATE Latin1_General_BIN2 NULL,
endpoint sysname COLLATE Latin1_General_BIN2 NULL,
appl nvarchar(128) COLLATE Latin1_General_BIN2 NULL,
dbname sysname COLLATE Latin1_General_BIN2 NULL,
prcstatus varchar(60) COLLATE Latin1_General_BIN2 NULL,
spid_ varchar(30) COLLATE Latin1_General_BIN2 NULL,
opntrn varchar(10) COLLATE Latin1_General_BIN2 NULL,
trninfo varchar(30) COLLATE Latin1_General_BIN2 NULL,
blklvl char(3) COLLATE Latin1_General_BIN2 NULL,
blkby varchar(30) COLLATE Latin1_General_BIN2 NULL,
cnt varchar(10) COLLATE Latin1_General_BIN2 NULL,
object nvarchar(520) COLLATE Latin1_General_BIN2 NULL,
rsctype varchar(60) COLLATE Latin1_General_BIN2 NULL,
locktype varchar(60) COLLATE Latin1_General_BIN2 NULL,
lstatus varchar(60) COLLATE Latin1_General_BIN2 NULL,
ownertype varchar(60) COLLATE Latin1_General_BIN2 NULL,
rscsubtype varchar(60) COLLATE Latin1_General_BIN2 NULL,
waittime varchar(16) COLLATE Latin1_General_BIN2 NULL,
waittype varchar(60) COLLATE Latin1_General_BIN2 NULL,
spid__ varchar(30) COLLATE Latin1_General_BIN2 NULL,
cpu varchar(30) COLLATE Latin1_General_BIN2 NULL,
physio varchar(50) COLLATE Latin1_General_BIN2 NULL,
logreads varchar(50) COLLATE Latin1_General_BIN2 NULL,
tempdb varchar(50) COLLATE Latin1_General_BIN2 NULL,
now char(12) COLLATE Latin1_General_BIN2 NULL,
login_time varchar(16) COLLATE Latin1_General_BIN2 NULL,
last_batch varchar(16) COLLATE Latin1_General_BIN2 NULL,
trn_start varchar(16) COLLATE Latin1_General_BIN2 NULL,
last_since varchar(11) COLLATE Latin1_General_BIN2 NULL,
trn_since varchar(11) COLLATE Latin1_General_BIN2 NULL,
clr char(3) COLLATE Latin1_General_BIN2 NULL,
nstlvl char(3) COLLATE Latin1_General_BIN2 NULL,
spid___ varchar(30) COLLATE Latin1_General_BIN2 NULL,
inputbuffer nvarchar(4000) COLLATE Latin1_General_BIN2 NULL,
current_sp nvarchar(400) COLLATE Latin1_General_BIN2 NULL,
curstmt nvarchar(MAX) COLLATE Latin1_General_BIN2 NULL,
queryplan xml NULL,
last bit NOT NULL DEFAULT 0)
-- Do the recursive call.
INSERT #textmode (spid, command, login, host, hostprc, endpoint, appl,
dbname, prcstatus, spid_, opntrn, trninfo,
blklvl, blkby, cnt, object, rsctype, locktype, lstatus,
ownertype, rscsubtype, waittime, waittype, spid__, cpu,
physio, logreads, tempdb, now, login_time,
last_batch, trn_start, last_since, trn_since, clr, nstlvl,
spid___, inputbuffer, current_sp, curstmt, queryplan)
EXEC beta_lockinfo @allprocesses = @allprocesses, @textmode = 0,
@procdata = @procdata, @debug = @debug
-- inputbuffer is always NULL, as the recursive call skips that part.
-- We need to do that now.
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Getting input buffers, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
DECLARE C3 CURSOR FAST_FORWARD LOCAL FOR
SELECT DISTINCT spid
FROM #textmode
WHERE login <> 'SYSTEM PROCESS'
AND spid NOT LIKE '%/%'
OPEN C3
WHILE 1 = 1
BEGIN
FETCH C3 INTO @spid
IF @@fetch_status <> 0
BREAK
BEGIN TRY
INSERT @inputbuffer(eventtype, params, inputbuffer)
EXEC sp_executesql N'DBCC INPUTBUFFER (@spid) WITH NO_INFOMSGS',
N'@spid int', @spid
UPDATE @inputbuffer
SET spid = @spid
WHERE ident = scope_identity()
END TRY
BEGIN CATCH
INSERT @inputbuffer(inputbuffer, spid)
VALUES('Error getting inputbuffer: ' + error_message(), @spid)
END CATCH
END
DEALLOCATE C3
-- Copy to the temp table and remove line breaks while we're at it.
UPDATE #textmode
SET inputbuffer = replace(replace(i.inputbuffer,
char(10), ' '), char(13), ' ')
FROM #textmode t
JOIN @inputbuffer i ON CASE WHEN t.spid NOT LIKE '%/%'
THEN convert(int, t.spid)
END = i.spid
OPTION (KEEPFIXED PLAN)
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Adjusting result set for text mode, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
-- Mark last row.
UPDATE #textmode
SET last = 1
FROM #textmode f1
JOIN (SELECT spid, ident = MAX(ident)
FROM (SELECT ident,
spid = substring(spid, 1,
coalesce(nullif(
charindex('-', spid, 2) - 1,
-1), len(spid)))
FROM #textmode) AS x
GROUP BY spid) AS f2 ON f2.ident = f1.ident
OPTION (KEEPFIXED PLAN)
-- Local varibles for the max lengths of all columns.
DECLARE @spidlen varchar(5),
@commandlen varchar(5),
@loginlen varchar(5),
@hostlen varchar(5),
@hostprclen varchar(5),
@endpointlen varchar(5),
@appllen varchar(5),
@dbnamelen varchar(5),
@prcstatuslen varchar(5),
@opntrnlen varchar(5),
@trninfolen varchar(5),
@blkbylen varchar(5),
@cntlen varchar(5),
@objectlen varchar(5),
@rsctypelen varchar(5),
@locktypelen varchar(5),
@lstatuslen varchar(5),
@ownertypelen varchar(5),
@rscsubtypelen varchar(5),
@waittimelen varchar(5),
@waittypelen varchar(5),
@cpulen varchar(5),
@physiolen varchar(5),
@logreadslen varchar(5),
@tempdblen varchar(5),
@login_timelen varchar(5),
@last_batchlen varchar(5),
@trn_startlen varchar(5),
@last_sincelen varchar(5),
@trn_sincelen varchar(5),
@inputbufferlen varchar(5),
@current_splen varchar(5)
-- Get all maxlengths
SELECT @spidlen = convert(varchar(5), coalesce(nullif(max(len(spid)), 0), 1)),
@commandlen = convert(varchar(5), coalesce(nullif(max(len(command)), 0), 1)),
@loginlen = convert(varchar(5), coalesce(nullif(max(len(login)), 0), 1)),
@hostlen = convert(varchar(5), coalesce(nullif(max(len(host)), 0), 1)),
@hostprclen = convert(varchar(5), coalesce(nullif(max(len(hostprc)), 0), 1)),
@endpointlen = convert(varchar(5), coalesce(nullif(max(len(endpoint)), 0), 1)),
@appllen = convert(varchar(5), coalesce(nullif(max(len(appl)), 0), 1)),
@dbnamelen = convert(varchar(5), coalesce(nullif(max(len(dbname)), 0), 1)),
@prcstatuslen = convert(varchar(5), coalesce(nullif(max(len(prcstatus)), 0), 1)),
@opntrnlen = convert(varchar(5), coalesce(nullif(max(len(opntrn)), 0), 1)),
@trninfolen = convert(varchar(5), coalesce(nullif(max(len(trninfo)), 0), 1)),
@blkbylen = convert(varchar(5), coalesce(nullif(max(len(blkby)), 0), 1)),
@cntlen = convert(varchar(5), coalesce(nullif(max(len(cnt)), 0), 1)),
@objectlen = convert(varchar(5), coalesce(nullif(max(len(object)), 0), 1)),
@rsctypelen = convert(varchar(5), coalesce(nullif(max(len(rsctype)), 0), 1)),
@locktypelen = convert(varchar(5), coalesce(nullif(max(len(locktype)), 0), 1)),
@lstatuslen = convert(varchar(5), coalesce(nullif(max(len(lstatus)), 0), 1)),
@ownertypelen = convert(varchar(5), coalesce(nullif(max(len(ownertype)), 0), 1)),
@rscsubtypelen = convert(varchar(5), coalesce(nullif(max(len(rscsubtype)), 0), 1)),
@waittimelen = convert(varchar(5), coalesce(nullif(max(len(waittime)), 0), 1)),
@waittypelen = convert(varchar(5), coalesce(nullif(max(len(waittype)), 0), 1)),
@cpulen = convert(varchar(5), coalesce(nullif(max(len(cpu)), 0), 1)),
@physiolen = convert(varchar(5), coalesce(nullif(max(len(physio)), 0), 1)),
@logreadslen = convert(varchar(5), coalesce(nullif(max(len(logreads)), 0), 1)),
@tempdblen = convert(varchar(5), coalesce(nullif(max(len(tempdb)), 0), 1)),
@login_timelen = convert(varchar(5), coalesce(nullif(max(len(login_time)), 0), 1)),
@last_batchlen = convert(varchar(5), coalesce(nullif(max(len(last_batch)), 0), 1)),
@trn_startlen = convert(varchar(5), coalesce(nullif(max(len(trn_start)), 0), 1)),
@last_sincelen = convert(varchar(5), coalesce(nullif(max(len(ltrim(last_since))), 0), 1)),
@trn_sincelen = convert(varchar(5), coalesce(nullif(max(len(ltrim(trn_since))), 0), 1)),
@inputbufferlen = convert(varchar(5), coalesce(nullif(max(len(inputbuffer)), 0), 1)),
@current_splen = convert(varchar(5), coalesce(nullif(max(len(current_sp)), 0), 1))
FROM #textmode
OPTION (KEEPFIXED PLAN)
-- Remove line breaks in current statement
UPDATE #textmode
SET curstmt = replace(replace(curstmt, char(10), ''), char(13), '')
WHERE len(curstmt) > 0
OPTION (KEEPFIXED PLAN)
-- Return the #textdata table with dynamic lengths.
IF @debug = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Returning result set, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
EXEC ('SELECT spid = convert(varchar( ' + @spidlen + '), spid),
command = convert(varchar( ' + @commandlen + '), command),
login = convert(nvarchar( ' + @loginlen + '), login),
host = convert(nvarchar( ' + @hostlen + '), host),
hostprc = convert(varchar( ' + @hostprclen + '), hostprc),
endpoint = convert(varchar( ' + @endpointlen + '), endpoint),
appl = convert(nvarchar( ' + @appllen + '), appl),
dbname = convert(nvarchar( ' + @dbnamelen + '), dbname),
prcstatus = convert(varchar( ' + @prcstatuslen + '), prcstatus),
spid_ = convert(varchar( ' + @spidlen + '), spid),
opntrn = convert(varchar( ' + @opntrnlen + '), opntrn),
trninfo = convert(varchar( ' + @trninfolen + '), trninfo),
blklvl,
blkby = convert(varchar( ' + @blkbylen + '), blkby),
cnt = convert(varchar( ' + @cntlen + '), cnt),
object = convert(nvarchar( ' + @objectlen + '), object),
rsctype = convert(varchar( ' + @rsctypelen + '), rsctype),
locktype = convert(varchar( ' + @locktypelen + '), locktype),
lstatus = convert(varchar( ' + @lstatuslen + '), lstatus),
ownertype = convert(varchar( ' + @ownertypelen + '), ownertype),
rscsubtype = convert(varchar( ' + @rscsubtypelen + '), rscsubtype),
waittime = convert(varchar( ' + @waittimelen + '), waittime),
waittype = convert(varchar( ' + @waittypelen + '), waittype),
spid__ = convert(varchar( ' + @spidlen + '), spid),
cpu = convert(varchar( ' + @cpulen + '), cpu),
physio = convert(varchar( ' + @physiolen + '), physio),
logreads = convert(varchar( ' + @logreadslen + '), logreads),
tempdb = convert(varchar( ' + @tempdblen + '), tempdb),
now,
login_time = convert(varchar( ' + @login_timelen + '), login_time),
last_batch = convert(varchar( ' + @last_batchlen + '), last_batch),
trn_start = convert(varchar( ' + @trn_startlen + '), trn_start),
last_since = convert(varchar( ' + @last_sincelen + '), ltrim(last_since)),
trn_since = convert(varchar( ' + @trn_sincelen + '), ltrim(trn_since)),
clr,
nstlvl,
spid___ = convert(varchar( ' + @spidlen + '), spid),
inputbuffer = convert(nvarchar( ' + @inputbufferlen + '), inputbuffer),
current_sp = convert(nvarchar( ' + @current_splen + '), current_sp),
curstmt,
CASE last WHEN 1 THEN char(10) ELSE '' '' END
FROM #textmode
ORDER BY ident
OPTION (KEEPFIXED PLAN)')
END
IF @debug = 1 AND @@nestlevel = 1
BEGIN
SELECT @ms = datediff(ms, @now, getdate())
RAISERROR ('Completed, time %d ms.', 0, 1, @ms) WITH NOWAIT
END
GO
/****** Object: StoredProcedure [dbo].[utility_EmailHtmlStringToHtmlTable] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: send the text as html report
-- =============================================
CREATE PROCEDURE [dbo].[utility_EmailHtmlStringToHtmlTable]
(
@p_Subject NVARCHAR(200),
@p_HtmlString NVARCHAR(MAX)
)
AS
BEGIN
--send email by send inti db email
EXEC dbo.utility_SendInitDBEmail @p_Subject=@p_Subject,
@p_Body=@p_HtmlString
END
GO
/****** Object: StoredProcedure [dbo].[utility_EmailProcedureToHtmlTable] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Send the procedure result by html report
-- =============================================
CREATE PROCEDURE [dbo].[utility_EmailProcedureToHtmlTable]
(
@p_Subject NVARCHAR(200),
@p_Procedure NVARCHAR(MAX)
)
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @l_Subject NVARCHAR(200)
DECLARE @l_SqlQuery NVARCHAR(MAX)
SET @l_SqlQuery='SELECT * FROM OPENQUERY(HelpServer,'''+@p_Procedure+''')'
EXEC dbo.utility_EmailQueryToHtmlTable @p_Subject=@p_Subject,
@p_SqlQuery=@l_SqlQuery
END
GO
/****** Object: StoredProcedure [dbo].[utility_EmailQueryToHtmlTable] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Send the query's result by html report
-- =============================================
CREATE PROCEDURE [dbo].[utility_EmailQueryToHtmlTable]
(
@p_Subject NVARCHAR(200),
@p_SqlQuery NVARCHAR(MAX)
)
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @l_Html NVARCHAR(MAX)
DECLARE @l_QHeader NVARCHAR(MAX)
DECLARE @l_QColumn NVARCHAR(MAX)
DECLARE @l_TColumn NVARCHAR(MAX)
DECLARE @l_TQuery NVARCHAR(MAX)
DECLARE @l_CSS NVARCHAR(MAX)
SET @l_Html =''
SET @l_QHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_CSS= '<style type="text/css">
table.gridtable {
font-family: verdana,arial,sans-serif;
font-size:11px;
color:#333333;
border-width: 1px;
border-color: #666666;
border-collapse: collapse; }
table.gridtable th {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #dedede;}
table.gridtable td {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #ffffff;}
</style>'
SET @l_TQuery = 'SELECT * INTO #TColumns FROM ( ' + @p_SqlQuery + ') Temp '
SET @l_TQuery=@l_TQuery+ ' SELECT @l_TColumn = @l_TColumn + name + '', ''
FROM tempdb.sys.columns
WHERE object_id = object_id('+'''tempdb..#TColumns'''+')'
SET @l_TQuery=@l_TQuery +' DROP TABLE tempdb..#TColumns'
SET @l_TQuery=@l_TQuery + ' SET @l_TColumn = LEFT(@l_TColumn,LEN(@l_TColumn)-1)'
EXECUTE sp_executesql @l_TQuery ,N'@l_TColumn NVARCHAR(MAX) OUTPUT',@l_TColumn OUTPUT
SELECT @l_QColumn = @l_QColumn + 'ISNULL(' + 'CAST('+Value +' AS NVARCHAR(MAX))' +' ,'''')' + ' AS TD, '
FROM dbo.fn_SplitStringToTable(@l_TColumn,',')
SET @l_QColumn = LEFT(@l_QColumn,LEN(@l_QColumn)-1)
SELECT @l_QHeader = @l_QHeader + '<TH>' + Value + '</TH>'
FROM dbo.fn_SplitStringToTable(@l_TColumn,',')
SET @l_QHeader = '<TR>' + @l_QHeader + '</TR>'
SET @l_TQuery = 'SET @Html = (SELECT ' + @l_QColumn + ' FROM ( ' + @p_SqlQuery + ') AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS)'
SELECT @l_TQuery
EXECUTE sp_executesql @l_TQuery,N'@Html NVARCHAR(MAX) OUTPUT',@l_Html OUTPUT
SET @l_Html = @l_CSS + REPLACE(@l_Html,'<TABLE>' ,'<TABLE class="gridtable">' + @l_QHeader)
--send email by send inti db email
EXEC dbo.utility_SendInitDBEmail @p_Subject=@p_Subject,
@p_Body=@l_Html
END
GO
/****** Object: StoredProcedure [dbo].[utility_INDEX_GetIndexFragementInfoForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get frgement info for all databases on a given server
-- =============================================
CREATE PROCEDURE [dbo].[utility_INDEX_GetIndexFragementInfoForAllDatabase]
@p_IsAlert BIT = 0
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
CREATE TABLE #FragmentedIndexes
( DatabaseName NVARCHAR(200),
SchemaName NVARCHAR(200),
TableName NVARCHAR(200),
IndexName NVARCHAR(200),
[Fragmentation%] FLOAT )
EXEC sp_MSforeachdb 'USE [?];
INSERT INTO #FragmentedIndexes
SELECT DB_NAME(DB_ID()) AS DatabaseName,
sc.name AS SchemaName,
OBJECT_NAME (s.object_id) AS TableName,
i.name AS IndexName,
s.avg_fragmentation_in_percent AS [Fragmentation%]
FROM sys.dm_db_index_physical_stats(db_id(),NULL, NULL, NULL,''SAMPLED'') s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas sc ON sc.[schema_id] = o.[schema_id]
WHERE s.database_id = DB_ID()
AND i.index_id != 0
AND s.record_count > 0
AND s.avg_fragmentation_in_percent>5
AND o.is_ms_shipped = 0 ;'
--Generate rebuild/reorganize index script
SELECT
CASE WHEN [Fragmentation%] > 30
THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(DatabaseName) + '.'+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName) + ' REBUILD;'
WHEN [Fragmentation%] > 10
THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(DatabaseName) + '.'+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName) + ' REORGANIZE;' END AS MaintanceScript
INTO #TScript
FROM #FragmentedIndexes
WHERE [Fragmentation%] > 10
IF @p_IsAlert=0
SELECT * FROM #FragmentedIndexes
SELECT * FROM #TScript
--send alert report part
IF EXISTS(SELECT 1 FROM #FragmentedIndexes WHERE @p_IsAlert=1 AND [Fragmentation%]>=10 )
BEGIN
SELECT * INTO #TAlert FROM #FragmentedIndexes WHERE [Fragmentation%]>=10
SELECT * INTO #TAlert1 FROM #TScript
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
--for #TAlert part
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Get Index Fragement From All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TAlert')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TAlert AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
--for #TAlert1 part
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Get Index Fragement From All Database'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TAlert1')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TAlert1 AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TAlert
DROP TABLE #TAlert1
END
DROP TABLE #FragmentedIndexes
DROP TABLE #TScript
END
GO
/****** Object: StoredProcedure [dbo].[utility_INDEX_GetStatisticsStateInfoForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get statistics state info for all database
-- =============================================
CREATE PROCEDURE [dbo].[utility_INDEX_GetStatisticsStateInfoForAllDatabase]
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NOCOUNT ON
SELECT DB_NAME() AS DBName,
ss.name AS SchemaName,
st.name AS TableName,
s.name AS IndexName,
STATS_DATE(s.id,s.indid) AS [Statistics Last Updated],
s.rowcnt AS [Row Count],
s.rowmodctr AS [Number Of Changes],
CAST((CAST(s.rowmodctr AS DECIMAL(28,8))/CAST(s.rowcnt AS DECIMAL(28,2)) * 100.0) AS DECIMAL(28,2)) AS [% Rows Changed]
INTO #TResult
FROM sys.sysindexes s
INNER JOIN sys.tables st ON st.[object_id] = s.[id]
INNER JOIN sys.schemas ss ON ss.[schema_id] = st.[schema_id]
WHERE 1=2
EXEC sp_MSforeachdb 'USE [?];
INSERT INTO #TResult
SELECT DB_NAME() AS DBName,
ss.name AS SchemaName,
st.name AS TableName,
s.name AS IndexName,
STATS_DATE(s.id,s.indid) AS [Statistics Last Updated],
s.rowcnt AS [Row Count],
s.rowmodctr AS [Number Of Changes],
CAST((CAST(s.rowmodctr AS DECIMAL(28,8))/CAST(s.rowcnt AS DECIMAL(28,2)) * 100.0) AS DECIMAL(28,2)) AS [% Rows Changed]
FROM sys.sysindexes s
INNER JOIN sys.tables st ON st.[object_id] = s.[id]
INNER JOIN sys.schemas ss ON ss.[schema_id] = st.[schema_id]
WHERE s.id > 100
AND s.indid > 0
AND s.rowcnt >= 500
ORDER BY SchemaName, TableName, IndexName'
SELECT * FROM #TResult
DROP TABLE #TResult
END
GO
/****** Object: StoredProcedure [dbo].[utility_INDEX_GetTopMissingIndexForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- Purpose:
-- Create Date: 08/29/2012
-- Last Update: 08/29/2012
-- Author: Alex Tian
CREATE PROCEDURE [dbo].[utility_INDEX_GetTopMissingIndexForAllDatabase]
@p_IsAlert BIT = 0
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
'CREATE NONCLUSTERED INDEX '+
QUOTENAME('IX_AutoGenerated_'+
REPLACE(REPLACE(CONVERT(VARCHAR(25), GETDATE(), 113), ' ', '_'), ':', '_')+
'_' + CAST(d.index_handle AS VARCHAR(22)))+ ' ON ' + d.[statement] +
'('+ CASE
WHEN d.equality_columns IS NULL THEN d.inequality_columns
WHEN d.inequality_columns IS NULL THEN d.equality_columns
ELSE d.equality_columns + ',' + d.inequality_columns END + ')'+
CASE WHEN d.included_columns IS NOT NULL THEN ' INCLUDE ( ' + d.included_columns + ')'
ELSE '' END AS MissingIndexSQL,
ROUND(s.avg_total_user_cost * s.avg_user_impact * (s.user_seeks + s.user_scans),0) AS [Total Cost],
d.[statement] AS [Table Name],
d.equality_columns,
d.inequality_columns,
d.included_columns
INTO #MissingIndexes
FROM sys.dm_db_missing_index_groups g
INNER JOIN sys.dm_db_missing_index_group_stats s ON s.group_handle = g.index_group_handle
INNER JOIN sys.dm_db_missing_index_details d ON d.index_handle = g.index_handle
ORDER BY [Total Cost] DESC
SELECT MissingIndexSQL AS MaintanceScript INTO #TScript
FROM #MissingIndexes
IF @p_IsAlert=0
SELECT * FROM #MissingIndexes
SELECT * FROM #TScript
--send alert report part
IF EXISTS(SELECT 1 FROM #MissingIndexes WHERE @p_IsAlert=1)
BEGIN
SELECT * INTO #TAlert FROM #MissingIndexes
SELECT * INTO #TAlert1 FROM #TScript
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
--for #TAlert part
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Get Top Missing Index'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TAlert')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TAlert AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
--for #TAlert1 part
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Get Top Missing Index'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TAlert1')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TAlert1 AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TAlert
DROP TABLE #TAlert1
END
DROP TABLE #MissingIndexes
DROP TABLE #TScript
END
GO
/****** Object: StoredProcedure [dbo].[utility_INDEX_GetUnusedIndexForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Find unused indexes for all database
-- =============================================
CREATE PROCEDURE [dbo].[utility_INDEX_GetUnusedIndexForAllDatabase]
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NOCOUNT ON
SELECT DB_NAME() AS DatabaseName,
SCHEMA_NAME(o.Schema_ID) AS SchemaName,
OBJECT_NAME(s.[object_id]) AS TableName,
i.name AS IndexName,
s.user_updates,
s.system_seeks + s.system_scans + s.system_lookups AS [System usage]
INTO #TempUnusedIndexes
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
INNER JOIN sys.objects o ON i.object_id = o.object_id
WHERE 1=2
EXEC sp_MSforeachdb 'USE [?];
INSERT INTO #TempUnusedIndexes
SELECT TOP 20
DB_NAME() AS DatabaseName,
SCHEMA_NAME(o.Schema_ID) AS SchemaName,
OBJECT_NAME(s.[object_id]) AS TableName,
i.name AS IndexName,
s.user_updates,
s.system_seeks + s.system_scans + s.system_lookups AS [System usage]
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
INNER JOIN sys.objects o ON i.object_id = o.object_id
WHERE s.database_id = DB_ID()
AND OBJECTPROPERTY(s.[object_id], ''IsMsShipped'') = 0
AND user_seeks = 0
AND user_scans = 0
AND user_lookups = 0
AND i.name IS NOT NULL
ORDER BY user_updates DESC'
DECLARE @DisableOrDrop INT
DECLARE @DisableIndexesSQL NVARCHAR(MAX)
SET @DisableOrDrop = 1
SET @DisableIndexesSQL = ''
SELECT CASE
WHEN @DisableOrDrop = 1
THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(DatabaseName) + '.'+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName) + ' DISABLE;'
ELSE CHAR(10) + 'DROP INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(DatabaseName) + '.'+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName)
END AS MaintanceScript INTO #TMS
FROM #TempUnusedIndexes
SELECT * FROM #TempUnusedIndexes
SELECT * FROM #TMS
DROP TABLE #TempUnusedIndexes
DROP TABLE #TMS
END
GO
/****** Object: StoredProcedure [dbo].[utility_IO_GetIOStallAtFileLevelForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Finding IO stall at file level
-- =============================================
CREATE PROCEDURE [dbo].[utility_IO_GetIOStallAtFileLevelForAllDatabase]
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NOCOUNT ON
SELECT DB_NAME(database_id) AS [DatabaseName],
file_id,
SUM(CAST(io_stall / 1000.0 AS DECIMAL(20,2))) AS [IO stall (secs)],
SUM(CAST(num_of_bytes_read / 1024.0 / 1024.0 AS DECIMAL(20,2))) AS [IO read (MB)],
SUM(CAST(num_of_bytes_written / 1024.0 / 1024.0 AS DECIMAL(20,2))) AS [IO written (MB)],
SUM(CAST((num_of_bytes_read + num_of_bytes_written)/ 1024.0 / 1024.0 AS DECIMAL(20,2))) AS [TotalIO (MB)]
FROM sys.dm_io_virtual_file_stats(NULL, NULL)
GROUP BY database_id, file_id
ORDER BY [IO stall (secs)] DESC
END
GO
/****** Object: StoredProcedure [dbo].[utility_IO_GetIOWaitAtFileLevelForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Finding database file io waits
-- =============================================
CREATE PROCEDURE [dbo].[utility_IO_GetIOWaitAtFileLevelForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT DB_NAME(database_id) AS [Database Name] ,
file_id AS [File ID],
io_stall_read_ms AS [Total Read Waits (ms)],
num_of_reads AS [Number of Reads],
CAST(io_stall_read_ms / ( 1.0 + num_of_reads ) AS NUMERIC(10, 1)) AS [Average Read Wait (ms)] ,
io_stall_write_ms AS [Total Write Waits (ms)],
num_of_writes AS [Number of Writes],
CAST(io_stall_write_ms / ( 1.0 + num_of_writes ) AS NUMERIC(10, 1)) AS [Average Write Wait (ms)] ,
io_stall_read_ms + io_stall_write_ms AS [Total I/O Waits (ms)] ,
num_of_reads + num_of_writes AS [Number of I/O Operations] ,
CAST(( io_stall_read_ms + io_stall_write_ms ) / ( 1.0 + num_of_reads + num_of_writes)AS NUMERIC(10,1)) AS [Average I/O Wait (ms)]
FROM sys.dm_io_virtual_file_stats(NULL, NULL)
ORDER BY [Average I/O Wait (ms)] DESC ;
END
GO
/****** Object: StoredProcedure [dbo].[utility_IO_GetTotalReadWriteTimesForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Finding the total reads and writes for each database
-- =============================================
CREATE PROCEDURE [dbo].[utility_IO_GetTotalReadWriteTimesForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT DB_NAME(qt.dbid) AS DatabaseName,
SUM(qs.total_logical_reads) AS [Total Reads],
SUM(qs.total_logical_writes) AS [Total Writes]
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
GROUP BY DB_NAME(qt.dbid)
ORDER BY [Total Reads] DESC,[Total Writes] DESC
END
GO
/****** Object: StoredProcedure [dbo].[utility_JOB_GetJobSummaryInfo] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- Purpose: get job summary list
-- Create Date: 08/29/2012
-- Last Update: 08/29/2012
-- Author: Alex Tian
CREATE PROCEDURE [dbo].[utility_JOB_GetJobSummaryInfo]
@p_IsAlert BIT=0, --Report need more restrict
@p_JobName VARCHAR(255) = NULL, -- Optional job name filter
@p_ShowDisabled BIT = 0, -- Include disabled jobs?
@p_ShowUnscheduled BIT = 0, -- Include Unscheduled jobs?
@p_JobThresholdSec INT = 0, -- If positive, show only the jobs with LAST duration above this.
@p_AvgExecThresholdSec INT = 0 -- If positive, show only the jobs with AVERAGE duration above this.
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * INTO #TJob
FROM ( SELECT JobName,
ISNULL(LastStep,'') LastStep,
CASE WHEN StartDate IS NOT NULL AND FinishDate IS NULL THEN 'Running'
WHEN Enabled = 0 THEN 'Disabled'
WHEN StepCount = 0 THEN 'No steps'
WHEN RunStatus IS NOT NULL THEN RunStatus
WHEN ScheduleCount = 0 THEN 'Not scheduled'
ELSE 'UNKNOWN' END Info,
DatabaseName,
Enabled,
ScheduleCount,
StepCount,
StartDate,
FinishDate,
DurationSec,
RIGHT('0'+convert(varchar(5),DurationSec/3600),2)+':'+
RIGHT('0'+convert(varchar(5),DurationSec%3600/60),2)+':'+
RIGHT('0'+convert(varchar(5),(DurationSec%60)),2) DurationSecFormatted,
avgDurationSec,
RIGHT('0'+convert(varchar(5),avgDurationSec/3600),2)+':'+
RIGHT('0'+convert(varchar(5),avgDurationSec%3600/60),2)+':'+
RIGHT('0'+convert(varchar(5),(avgDurationSec%60)),2) avgDurationSecFormatted,
CASE WHEN (DurationSec IS NULL OR ISNULL(avgDurationSec, 0) = 0) THEN 0
ELSE CONVERT(DECIMAL(18,2), (100*CAST(DurationSec AS DECIMAL)) / CAST (avgDurationSec as DECIMAL)) END AS DurationRatio,
NextRunDate,
StepCommand,
HistoryMessage
FROM ( SELECT j.name JobName,
j.enabled Enabled,
(SELECT COUNT(1) FROM msdb..sysjobschedules jss WHERE jss.job_id = j.job_id) ScheduleCount,
(SELECT COUNT(1) FROM msdb..sysjobsteps jps WHERE jps.job_id = j.job_id) StepCount,
ls1.job_history_id HistoryID,
ls1.start_execution_date StartDate,
ls1.stop_execution_date FinishDate,
ls1.last_executed_step_id LastStepID,
DATEDIFF(SECOND,
ls1.start_execution_date,
CASE WHEN ls1.stop_execution_date IS NULL THEN GETDATE()
ELSE ls1.stop_execution_date END) DurationSec,
ISNULL(avgSec, 0) avgDurationSec,
ls1.next_scheduled_run_date NextRunDate,
st.step_name LastStep,
st.command StepCommand,
st.database_name DatabaseName,
h.message HistoryMessage,
CASE WHEN h.job_id IS NULL THEN 'Never Run'
ELSE CASE h.run_status WHEN 0 THEN 'Failed'
WHEN 1 THEN 'Succeeded'
WHEN 2 THEN 'Retry'
WHEN 3 THEN 'Canceled' END END RunStatus,
h.run_date rawRunDate,
h.run_time rawRunTime,
h.run_duration rawRunDuration
FROM msdb..sysjobactivity ls1 (NOLOCK)
INNER JOIN msdb..sysjobs j (NOLOCK) ON ls1.job_id = j.job_id
INNER JOIN (SELECT job_id JobID,
MAX(session_id) LastSessionID
FROM msdb..sysjobactivity (NOLOCK)
GROUP BY job_id ) ls2 ON ls1.job_id = ls2.JobID
AND ls1.session_id = ls2.LastSessionID
LEFT OUTER JOIN msdb..sysjobsteps st (NOLOCK) ON st.job_id = j.job_id
AND ls1.last_executed_step_id = st.step_id
LEFT OUTER JOIN msdb..sysjobhistory h (NOLOCK) ON h.instance_id = ls1.job_history_id
LEFT OUTER JOIN ( SELECT j.job_id JobID,
SUM(h.avgSecs) avgSec
FROM msdb..sysjobs j (NOLOCK)
INNER JOIN ( SELECT job_id,
step_id,
AVG(run_duration/10000*3600 +
run_duration%10000/100*60 +
run_duration%100) avgSecs
FROM msdb..sysjobhistory
WHERE step_id > 0
AND run_status = 1
GROUP BY job_id,
step_id ) h ON j.job_id = h.job_id
GROUP BY j.job_id ) jobavg ON jobavg.JobID = j.job_id )jj
WHERE (@p_ShowDisabled = 1 OR (StartDate IS NOT NULL AND FinishDate IS NULL) OR Enabled = 1)
AND (@p_JobName IS NULL OR JobName = @p_JobName)
AND (@p_ShowUnscheduled = 1 OR (StartDate IS NOT NULL AND FinishDate IS NULL) OR ScheduleCount > 0)
AND (@p_JobThresholdSec = 0 OR DurationSec >= @p_JobThresholdSec)
AND (@p_AvgExecThresholdSec = 0 OR avgDurationSec >= @p_AvgExecThresholdSec))x
ORDER BY CASE Info
WHEN 'Running' THEN 0
WHEN 'Failed' THEN 1
WHEN 'Retry' THEN 2
WHEN 'Succeeded' THEN 3
WHEN 'Canceled' THEN 4
WHEN 'No steps' THEN 5
WHEN 'Not scheduled' THEN 6
WHEN 'Disabled' THEN 7
WHEN 'Never Run' THEN 8
WHEN 'UNKNOWN' THEN -1
ELSE -2 END,
NextRunDate,
JobName
IF @p_IsAlert=0
SELECT * FROM #TJob
--send alert report part
IF EXISTS(SELECT 1 FROM #TJob WHERE @p_IsAlert=1 AND Info IN ('Failed','UNKNOWN','Never Run','Disabled','No steps','Canceled') )
BEGIN
SELECT * INTO #TAlert FROM #TJob WHERE Info IN ('Failed','UNKNOWN','Never Run','Disabled','No steps','Canceled')
DECLARE @l_Html NVARCHAR(max)
DECLARE @l_HHeader NVARCHAR(max)
DECLARE @l_QColumn NVARCHAR(max)
DECLARE @l_TColumn NVARCHAR(max)
DECLARE @l_TQuery NVARCHAR(max)
DECLARE @l_EmailSubject NVARCHAR(200)
DECLARE @l_EmailBody NVARCHAR(max)
SET @l_Html =''
SET @l_HHeader =''
SET @l_QColumn =''
SET @l_TColumn =''
SET @l_TQuery =''
SET @l_EmailSubject='Schedule Job Summary'
SET @l_EmailBody=''
SELECT @l_TColumn = @l_TColumn + name + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#TAlert')
SET @l_TColumn=LEFT(@l_TColumn, LEN(@l_TColumn) - 1)
SET @l_QColumn=dbo.fn_SplitStringToQueryColumn(@l_TColumn, ',')
SET @l_HHeader=dbo.fn_SplitStringToHtmlHeader(@l_TColumn, ',')
SET @l_TQuery = 'SET @Html = ( SELECT ' + @l_QColumn +
' FROM #TAlert AS TR
FOR XML RAW(''TR'') ,ROOT(''TABLE''), ELEMENTS )'
EXECUTE sp_executesql @l_TQuery,
N'@Html NVARCHAR(MAX) OUTPUT',
@l_Html OUTPUT
SET @l_EmailBody=dbo.fn_FormatHtmlTable(@l_Html, @l_HHeader)
EXECUTE dbo.utility_EmailHtmlStringToHtmlTable @p_Subject=@l_EmailSubject,
@p_HtmlString=@l_EmailBody
DROP TABLE #TAlert
END
DROP TABLE #TJob
END
GO
/****** Object: StoredProcedure [dbo].[utility_LOG_GetCustomSQLErrorLog] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get error log from application
-- =============================================
CREATE PROCEDURE [dbo].[utility_LOG_GetCustomSQLErrorLog]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @l_TimeStart DATETIME
SET @l_TimeStart=DATEADD(DAY,-1,GETDATE());
SELECT *
FROM dbo.ErrorLog
WHERE DATEDIFF(DAY,Time,GETDATE())<=1
ORDER BY DBName,Time DESC
END
GO
/****** Object: StoredProcedure [dbo].[utility_LOG_GetSQLAgentLog] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get sql server error log
-- 1.Value of error log file you want to read: 0 = current, 1 = Archive #1, 2 = Archive #2, etc...
-- 2.Log file type: 1 or NULL = error log, 2 = SQL Agent log
-- 3.Search string 1: String one you want to search for
-- 4.Search string 2: String two you want to search for to further refine the results
-- =============================================
CREATE PROCEDURE [dbo].[utility_LOG_GetSQLAgentLog]
(
@p_p1 INT = 0,
@p_p2 INT = 2,
@p_p3 VARCHAR(255) = NULL,
@p_p4 VARCHAR(255) = NULL
)
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @l_TimeStart DATETIME
DECLARE @l_TimeEnd DATETIME
SET @l_TimeStart=DATEADD(DAY,-1,GETDATE());
SET @l_TimeEnd=GETDATE();
IF (NOT IS_SRVROLEMEMBER(N'securityadmin') = 1)
BEGIN
RAISERROR(15003,-1,-1, N'securityadmin')
RETURN (1)
END
IF (@p_p2 IS NULL)
EXEC master.sys.xp_readerrorlog @p_p1
ELSE
EXEC master.sys.xp_readerrorlog @p_p1,@p_p2,@p_p3,@p_p4,@l_TimeStart,@l_TimeEnd
END
GO
/****** Object: StoredProcedure [dbo].[utility_LOG_GetSQLServerErrorLog] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get sql server error log
-- 1.Value of error log file you want to read: 0 = current, 1 = Archive #1, 2 = Archive #2, etc...
-- 2.Log file type: 1 or NULL = error log, 2 = SQL Agent log
-- 3.Search string 1: String one you want to search for
-- 4.Search string 2: String two you want to search for to further refine the results
-- =============================================
CREATE PROCEDURE [dbo].[utility_LOG_GetSQLServerErrorLog]
(
@p_p1 INT = 0,
@p_p2 INT = 1,
@p_p3 VARCHAR(255) = NULL,
@p_p4 VARCHAR(255) = NULL
)
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @l_TimeStart DATETIME
DECLARE @l_TimeEnd DATETIME
SET @l_TimeStart=DATEADD(DAY,-1,GETDATE());
SET @l_TimeEnd=GETDATE();
IF (NOT IS_SRVROLEMEMBER(N'securityadmin') = 1)
BEGIN
RAISERROR(15003,-1,-1, N'securityadmin')
RETURN (1)
END
IF (@p_p2 IS NULL)
EXEC master.sys.xp_readerrorlog @p_p1
ELSE
EXEC master.sys.xp_readerrorlog @p_p1,@p_p2,@p_p3,@p_p4,@l_TimeStart,@l_TimeEnd
END
GO
/****** Object: StoredProcedure [dbo].[utility_LOG_GetWeeklyEventLog] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get the latest event log
-- =============================================
CREATE PROCEDURE [dbo].[utility_LOG_GetWeeklyEventLog]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @l_BeginDate SMALLDATETIME
DECLARE @l_EndDate SMALLDATETIME
DECLARE @l_DateNow SMALLDATETIME
SET @l_DateNow = CONVERT(VARCHAR(10), GETDATE(), 120)
SET @l_BeginDate = DATEADD(d, - DATEPART(dw, @l_DateNow) - 7, @l_DateNow)
SET @l_EndDate = DATEADD(d, - DATEPART(dw, @l_DateNow), @l_DateNow)
SELECT EventData.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'varchar(128)') AS DatabaseName,
EventData.value('(/EVENT_INSTANCE/EventType)[1]', 'varchar(128)') AS EventType,
EventData.value('(/EVENT_INSTANCE/UserName)[1]', 'varchar(128)') AS UserName,
EventData.value('(/EVENT_INSTANCE/LoginName)[1]', 'varchar(128)') AS LoginName,
EventData.value('(/EVENT_INSTANCE/PostTime)[1]', 'datetime') AS PostTime,
EventData.value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)') AS CommandText
FROM dbo.EventLog
WHERE EventData.value('(/EVENT_INSTANCE/PostTime)[1]', 'smalldatetime') >= @l_BeginDate
AND EventData.value('(/EVENT_INSTANCE/PostTime)[1]', 'smalldatetime') < @l_EndDate
END
GO
/****** Object: StoredProcedure [dbo].[utility_MEMORY_GetBufferCacheHitRatio] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get the buffer cache hit ratio
-- =============================================
CREATE PROCEDURE [dbo].[utility_MEMORY_GetBufferCacheHitRatio]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT (CAST(SUM(CASE LTRIM(RTRIM(counter_name))
WHEN 'Buffer cache hit ratio'
THEN CAST(cntr_value AS INTEGER)
ELSE NULL END) AS FLOAT) /
CAST(SUM(CASE LTRIM(RTRIM(counter_name))
WHEN 'Buffer cache hit ratio base'
THEN CAST(cntr_value AS INTEGER)
ELSE NULL END) AS FLOAT)) * 100 AS BufferCacheHitRatio
FROM sys.dm_os_performance_counters WITH (NOLOCK)
WHERE [object_name] LIKE 'SQLServer:Buffer Manager%'
AND [counter_name] LIKE 'Buffer cache hit ratio%'
END
GO
/****** Object: StoredProcedure [dbo].[utility_MEMORY_GetMemoryUsedAtDatabaseLevelForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get memory used for all database
-- =============================================
CREATE PROCEDURE [dbo].[utility_MEMORY_GetMemoryUsedAtDatabaseLevelForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT ISNULL(DB_NAME(database_id), 'ResourceDb') AS DatabaseName,
CAST(COUNT(row_count) * 8.0 / (1024.0) AS DECIMAL(28,2)) AS [Size (MB)]
FROM sys.dm_os_buffer_descriptors
GROUP BY database_id
ORDER BY [Size (MB)] DESC ,DatabaseName
END
GO
/****** Object: StoredProcedure [dbo].[utility_QUERY_GetExtendedWhoProcedure] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Execute extended who procedure
-- Some Sample Usage:
-- EXEC dbo.query_GetExtendedWhoProcedure;
-- EXEC dbo.query_GetExtendedWhoProcedure 'active';
-- EXEC dbo.query_GetExtendedWhoProcedure 'active',@IncludeSQL = 1,@Brief = 1;
-- EXEC dbo.query_GetExtendedWhoProcedure 'active', @IncludeSelf = 1;
-- EXEC dbo.query_GetExtendedWhoProcedure @Loginame = 'sa';
-- EXEC dbo.query_GetExtendedWhoProcedure @OrderBy = 'CPU_Time';
-- EXEC dbo.query_GetExtendedWhoProcedure @IncludeSystemSPIDs = 1;
-- EXEC dbo.query_GetExtendedWhoProcedure @ShowBlockersOnly = 1;
-- EXEC dbo.query_GetExtendedWhoProcedure @SearchSPID = 58;
-- EXEC dbo.query_GetExtendedWhoProcedure @SearchDBName = 'SomeDatabaseName';
-- EXEC dbo.query_GetExtendedWhoProcedure @IncludeSQL = 1,@SearchCommand = '%update%sometable%';
-- =============================================
CREATE PROCEDURE [dbo].[utility_QUERY_GetExtendedWhoProcedure]
-- only show logins with this name
@Loginame VARCHAR(255) = 'active',
-- ShowBlockersOnly will reduce resultset to
-- those that are blocking or being blocked
@ShowBlockersOnly BIT = 0,
-- optional search conditions
@SearchSPID INT = NULL,
@SearchDBName NVARCHAR(255) = '%',
@SearchHostName NVARCHAR(255) = '%',
@SearchCommand NVARCHAR(255) = '%',
@SearchIP VARCHAR(16) = '%',
@SearchProgramName NVARCHAR(255) = '%',
-- unlikely you want to see yourself,
-- but stranger things can happen
@IncludeSelf BIT = 0,
-- show system SPIDs?
@IncludeSystemSPIDs BIT = 0,
-- augment exec_sql info with DBCC INPUTBUFFER
@IncludeSQL BIT = 1,
-- displays only the first 255 characters of SQL
@Brief BIT = 0,
-- optional sorting... allowed values:
-- 'Elapsed_Time', 'CPU_Time',
-- 'Logical_Reads', 'Reads', 'Writes'
@OrderBy VARCHAR(32) = NULL
AS
BEGIN
SET NOCOUNT ON;
SET ANSI_WARNINGS OFF;
DECLARE
@spid INT,
@sql NVARCHAR(MAX),
@briefsize SMALLINT;
-- used in conjunction with @Brief and @IncludeSQL
SET @briefsize = 255;
-- override @IncludeSQL otherwise nothing to search
IF @SearchCommand != '%'
SET @IncludeSQL = 1;
SELECT
[Spid] = s.[session_id],
[Status] = MAX(UPPER(COALESCE
(
r.[status],
tt.[task_state],
s.[status],
''
))),
[Command] = MAX(COALESCE
(
r.[command],
r.[wait_type],
wt.[wait_type],
r.[last_wait_type],
''
)),
[Blocked_By] = MAX(CONVERT(VARCHAR(12), COALESCE
(
RTRIM(NULLIF(r.[blocking_session_id], 0)),
' .'
))),
[Database_Name] = MAX(DB_NAME(COALESCE
(
tl.[database_id],
r.[database_id],
t.[database_id],
''
))),
[Logical_Reads] = MAX(COALESCE
(
NULLIF(r.[logical_reads], 0),
s.[logical_reads],
0
)),
[Reads] = MAX(COALESCE
(
NULLIF(r.[reads], 0),
NULLIF(s.[reads], 0),
c.[num_reads],
0
)),
[Writes] = MAX(COALESCE
(
NULLIF(r.[writes], 0),
NULLIF(s.[writes], 0),
c.[num_writes],
0
)),
[CPU_Time] = MAX(COALESCE
(
NULLIF(tt.[CPU_Time], 0),
NULLIF(r.[cpu_time], 0),
NULLIF(s.[cpu_time], 0),
s.[total_scheduled_time],
0
)),
[Elapsed_Time] = MAX(COALESCE
(
r.[total_elapsed_time],
s.[total_elapsed_time]
)),
[Row_Count] = MAX(s.[row_count]),
[Memory_In_Pages] = MAX(COALESCE
(
NULLIF(r.[granted_query_memory], 0),
s.[memory_usage],
0
)),
[Tran_Count] = MAX(COALESCE
(
t.[trancount],
0
)),
[Lock_Count] = MAX(COALESCE
(
tl.[lockcount],
0
)),
[Login_Name] = s.[login_name],
[Host_Name] = MAX(COALESCE
(
s.[host_name],
' .'
)),
[IP_Address] = MAX(COALESCE
(
c.[client_net_address],
' .'
)),
[Program_Name] = MAX(COALESCE
(
s.[program_name],
''
)),
[Login_Time] = MAX(COALESCE
(
s.[login_time],
c.[connect_time]
)),
[Last_Request] = MAX(COALESCE
(
r.[start_time],
s.[last_request_start_time]
)),
[Handle] = MAX(COALESCE
(
r.[sql_handle],
c.[most_recent_sql_handle]
)),
[Exec_SQL] = CONVERT(NVARCHAR(MAX), N'')
INTO
#spids
FROM
sys.dm_exec_sessions s
LEFT OUTER JOIN
sys.dm_exec_connections c
ON c.[session_id] = s.[session_id]
LEFT OUTER JOIN
sys.dm_exec_requests r
ON s.[session_id] = r.[session_id]
LEFT OUTER JOIN
(
SELECT
[session_id],
[database_id] = MAX([database_id]),
[trancount] = COUNT(*)
FROM
sys.dm_tran_session_transactions t
INNER JOIN
sys.dm_tran_database_transactions dt
ON
t.[transaction_id] = dt.[transaction_id]
GROUP BY
[session_id]
) t
ON s.[session_id] = t.[session_id]
LEFT OUTER JOIN
(
SELECT
[request_session_id],
[database_id] = MAX([resource_database_id]),
[lockcount] = COUNT(*)
FROM
sys.dm_tran_locks WITH (NOLOCK)
GROUP BY
[request_session_id]
) tl
ON
s.[session_id] = tl.[request_session_id]
LEFT OUTER JOIN
sys.dm_os_waiting_tasks wt
ON
s.[session_id] = wt.[session_id]
LEFT OUTER JOIN
(
SELECT
ot.[session_id],
ot.[task_state],
[CPU_Time] = MAX(oth.[usermode_time])
FROM
sys.dm_os_tasks ot
INNER JOIN
sys.dm_os_workers ow
ON
ot.[worker_address] = ow.[worker_address]
INNER JOIN
sys.dm_os_threads oth
ON
ow.[thread_address] = oth.[thread_address]
GROUP BY
ot.[session_id],
ot.[task_state]
) tt
ON
s.[session_id] = tt.[session_id]
WHERE
s.[login_name] = COALESCE
(
NULLIF(@Loginame, 'active'),
s.[login_name]
)
GROUP BY
s.[session_id],
s.[login_name];
-- delete rows we're not interested in
IF LOWER(@Loginame) = 'active'
BEGIN
DELETE #spids
WHERE UPPER([Status]) = 'SLEEPING'
OR UPPER([Command]) = 'AWAITING COMMAND';
END
IF @ShowBlockersOnly = 1
BEGIN
DELETE s1
FROM #spids s1
WHERE s1.[Blocked_By] = ' .'
AND NOT EXISTS
(
SELECT 1
FROM
#spids
WHERE
[Blocked_By] = RTRIM(s1.[Spid])
);
END
IF @SearchSPID IS NOT NULL
BEGIN
DELETE #spids
WHERE [Spid] != @SearchSPID;
END
IF @SearchDBName != '%'
BEGIN
DELETE #spids
WHERE [Database_Name] IS NULL
OR [Database_Name] NOT LIKE @SearchDBName;
END
IF @SearchHostName != '%'
OR @SearchProgramName != '%'
OR @SearchIP != '%'
BEGIN
DELETE #spids
WHERE [Host_Name] NOT LIKE @SearchHostName
OR [Program_Name] NOT LIKE @SearchProgramName
OR [IP_Address] NOT LIKE @SearchIP;
END
IF @IncludeSelf = 0
BEGIN
DELETE #spids
WHERE [Spid] = @@SPID;
END
IF @IncludeSystemSPIDs = 0
BEGIN
DELETE #spids
WHERE [Spid] <= 50;
END
CREATE TABLE #dbcc
(
a NVARCHAR(500),
b NVARCHAR(500),
[Input_Buffer] NVARCHAR(MAX),
[Spid] INT NULL
);
IF @IncludeSQL = 1
BEGIN
UPDATE #spids
SET [Exec_SQL] =
(
SELECT [text]
FROM sys.dm_exec_sql_text([Handle])
);
DECLARE dbcc_cursor CURSOR
LOCAL FORWARD_ONLY STATIC READ_ONLY
FOR
SELECT [Spid]
FROM #spids;
OPEN dbcc_cursor;
FETCH NEXT FROM dbcc_cursor INTO @spid;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = 'DBCC INPUTBUFFER('
+RTRIM(@spid)+')
WITH NO_INFOMSGS;';
INSERT #dbcc(a,b,[Input_Buffer])
EXEC sp_executesql @sql;
UPDATE #dbcc
SET [Spid] = @spid
WHERE [Spid] IS NULL;
FETCH NEXT FROM dbcc_cursor INTO @spid;
END
CLOSE dbcc_cursor;
DEALLOCATE dbcc_cursor;
IF @SearchCommand != '%'
BEGIN
DELETE #dbcc
WHERE COALESCE([Input_Buffer], '')
NOT LIKE @SearchCommand;
DELETE #spids
WHERE COALESCE([Exec_SQL], '')
NOT LIKE @SearchCommand;
END
IF @Brief = 1
BEGIN
UPDATE #dbcc
SET [Input_Buffer] =
COALESCE(LEFT([Input_Buffer], @briefsize), '');
UPDATE #spids
SET [Exec_SQL] =
COALESCE(LEFT([Exec_SQL], @briefsize), '');
END
END
SELECT
s.[Spid],
s.[Status],
s.[Command],
s.[Blocked_By],
s.[Database_Name],
s.[Logical_Reads],
s.[Reads],
s.[Writes],
s.[CPU_Time],
s.[Elapsed_Time],
s.[Row_Count],
s.[Memory_In_Pages],
s.[Tran_Count],
s.[Lock_Count],
s.[Login_Name],
s.[Host_Name],
s.[IP_Address],
s.[Program_Name],
s.[Login_Time],
s.[Last_Request],
s.[Exec_SQL],
[Input_Buffer] = COALESCE(d.[Input_Buffer], '')
FROM
#spids s
LEFT OUTER JOIN
#dbcc d
ON
s.[Spid] = d.[Spid]
ORDER BY
CASE @OrderBy
WHEN 'Elapsed_Time' THEN s.[Elapsed_Time]
WHEN 'CPU_Time' THEN s.[CPU_Time]
WHEN 'Logical_Reads' THEN s.[Logical_Reads]
WHEN 'Reads' THEN s.[Reads]
WHEN 'Writes' THEN s.[Writes]
END DESC,
s.[Spid];
DROP TABLE #dbcc, #spids;
END
GO
/****** Object: StoredProcedure [dbo].[utility_QUERY_GetTopLongestBlockedQueryForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: The queries spend the longest time being blocked for all database
-- =============================================
CREATE PROCEDURE [dbo].[utility_QUERY_GetTopLongestBlockedQueryForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
CAST((qs.total_elapsed_time - qs.total_worker_time) /1000000.0 AS DECIMAL(28,2)) AS [Total time blocked (s)],
CAST(qs.total_worker_time * 100.0 / qs.total_elapsed_time AS DECIMAL(28,2)) AS [% CPU],
CAST((qs.total_elapsed_time - qs.total_worker_time)* 100.0 /qs.total_elapsed_time AS DECIMAL(28, 2)) AS [% Waiting],
qs.execution_count,
CAST((qs.total_elapsed_time - qs.total_worker_time) / 1000000.0/ qs.execution_count AS DECIMAL(28, 2)) AS [Blocking average (s)],
SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1,((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query],
qt.text AS [Parent Query],
DB_NAME(qt.dbid) AS DatabaseName,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qs.total_elapsed_time > 0
ORDER BY [Total time blocked (s)] DESC
END
GO
/****** Object: StoredProcedure [dbo].[utility_QUERY_GetTopLongestTimeQueryForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: The queries that take the longest time to run for all database
-- =============================================
CREATE PROCEDURE [dbo].[utility_QUERY_GetTopLongestTimeQueryForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
CAST(qs.total_elapsed_time / 1000000.0 AS DECIMAL(28, 2))AS [Total Duration (s)],
CAST(qs.total_worker_time * 100.0 / qs.total_elapsed_time AS DECIMAL(28, 2))AS [% CPU],
CAST((qs.total_elapsed_time - qs.total_worker_time)* 100.0 /qs.total_elapsed_time AS DECIMAL(28, 2)) AS [% Waiting],
qs.execution_count,
CAST(qs.total_elapsed_time / 1000000.0 / qs.execution_count AS DECIMAL(28, 2))AS [Average Duration (s)],
SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1,((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query],
qt.text AS [Parent Query],
DB_NAME(qt.dbid) AS DatabaseName,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qs.total_elapsed_time > 0
ORDER BY qs.total_elapsed_time DESC
END
GO
/****** Object: StoredProcedure [dbo].[utility_QUERY_GetTopMostCPUCostQueryForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get the queries that use the most CPU for all database
-- =============================================
CREATE PROCEDURE [dbo].[utility_QUERY_GetTopMostCPUCostQueryForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
CAST((qs.total_worker_time) / 1000000.0AS DECIMAL(28,2)) AS [Total CPU time (s)],
CAST(qs.total_worker_time * 100.0 / qs.total_elapsed_time AS DECIMAL(28,2)) AS [% CPU],
CAST((qs.total_elapsed_time - qs.total_worker_time)* 100.0 /qs.total_elapsed_time AS DECIMAL(28, 2)) AS [% Waiting],
qs.execution_count,
CAST((qs.total_worker_time) / 1000000.0/ qs.execution_count AS DECIMAL(28, 2)) AS [CPU time average (s)],
SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1,((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query],
qt.text AS [Parent Query],
DB_NAME(qt.dbid) AS DatabaseName,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qs.total_elapsed_time > 0
ORDER BY [Total CPU time (s)] DESC
END
GO
/****** Object: StoredProcedure [dbo].[utility_QUERY_GetTopMostIOCostQueryForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get the queries that use the most I/O
-- =============================================
CREATE PROCEDURE [dbo].[utility_QUERY_GetTopMostIOCostQueryForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
[Total IO] = (qs.total_logical_reads + qs.total_logical_writes),
[Average IO] = (qs.total_logical_reads + qs.total_logical_writes) /qs.execution_count,
qs.execution_count,
SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1,((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query],
qt.text AS [Parent Query],
DB_NAME(qt.dbid) AS DatabaseName,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY [Total IO] DESC
END
GO
/****** Object: StoredProcedure [dbo].[utility_QUERY_GetTopMostOftenExecutedQueryForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: The queries that have been executed the most often
-- =============================================
CREATE PROCEDURE [dbo].[utility_QUERY_GetTopMostOftenExecutedQueryForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
qs.execution_count,
SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1,((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query],
qt.text AS [Parent Query],
DB_NAME(qt.dbid) AS DatabaseName,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY qs.execution_count DESC;
END
GO
/****** Object: StoredProcedure [dbo].[utility_QUERY_GetTopMostRecompiledQueryForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Determining your most-recompiled queries
-- =============================================
CREATE PROCEDURE [dbo].[utility_QUERY_GetTopMostRecompiledQueryForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 20
qs.plan_generation_num,
qs.total_elapsed_time,
qs.execution_count,
SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1,((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query],
qt.text AS [Parent Query],
DB_NAME(qt.dbid),
qs.creation_time,
qs.last_execution_time
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
ORDER BY plan_generation_num DESC
END
GO
/****** Object: StoredProcedure [dbo].[utility_QUERY_GetWhatProcessIsRunningForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get what process is running for all database
-- =============================================
CREATE PROCEDURE [dbo].[utility_QUERY_GetWhatProcessIsRunningForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT der.session_id AS SessionID,
der.status AS Status,
des.login_name AS Login,
des.[host_name] AS HostName,
DB_NAME(der.database_id) AS DatabaseName,
des.[program_name] AS Program,
der.command AS Command,
dest.text AS CommandText ,
des.cpu_time AS CPUTime,
des.memory_usage*8 AS MemoryUsage_KB,
des.reads AS Reads,
des.writes AS Writes,
des.logical_reads AS LogicalReads,
des.total_scheduled_time AS TotalScheduleTime,
des.login_time AS LoginTime,
dec.client_net_address AS ClientNetAddress,
des.client_interface_name AS ClientInterfaceName
FROM sys.dm_exec_requests der
INNER JOIN sys.dm_exec_connections dec ON der.session_id = dec.session_id
INNER JOIN sys.dm_exec_sessions des ON des.session_id = der.session_id
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS dest
ORDER BY CPUTime DESC ,MemoryUsage_KB DESC
END
GO
/****** Object: StoredProcedure [dbo].[utility_SPACE_GetDiskSpaceForServer] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get disk space
-- =============================================
CREATE PROCEDURE [dbo].[utility_SPACE_GetDiskSpaceForServer]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
IF @@microsoftversion / power(2, 24) >= 9
BEGIN
EXEC sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE WITH OVERRIDE
END
DECLARE @hr int
DECLARE @fso int
DECLARE @drive char(1)
DECLARE @odrive int
DECLARE @TotalSize varchar(20)
DECLARE @MB bigint ; SET @MB = 1048576
CREATE TABLE #drives (drive char(1) PRIMARY KEY,
FreeSpace int NULL,
TotalSize int NULL)
INSERT #drives(drive,FreeSpace)
EXEC master.dbo.xp_fixeddrives
EXEC @hr=sp_OACreate 'Scripting.FileSystemObject',@fso OUT
IF @hr <> 0 EXEC sp_OAGetErrorInfo @fso
DECLARE dcur CURSOR LOCAL FAST_FORWARD
FOR SELECT drive FROM #drives ORDER BY drive
OPEN dcur
FETCH NEXT FROM dcur INTO @drive
WHILE @@FETCH_STATUS=0
BEGIN
EXEC @hr = sp_OAMethod @fso,'GetDrive', @odrive OUT, @drive
IF @hr <> 0 EXEC sp_OAGetErrorInfo @fso
EXEC @hr = sp_OAGetProperty @odrive,'TotalSize', @TotalSize OUT
IF @hr <> 0 EXEC sp_OAGetErrorInfo @odrive
UPDATE #drives
SET TotalSize=@TotalSize/@MB
WHERE drive=@drive
FETCH NEXT FROM dcur INTO @drive
END
CLOSE dcur
DEALLOCATE dcur
EXEC @hr=sp_OADestroy @fso
IF @hr <> 0 EXEC sp_OAGetErrorInfo @fso
SELECT drive,
FreeSpace as 'Free(MB)',
TotalSize as 'Total(MB)',
CAST((FreeSpace/(TotalSize*1.0))*100.0 as int) as 'Free(%)'
FROM #drives ORDER BY drive
DROP TABLE #drives
IF @@microsoftversion / power(2, 24) >= 9
BEGIN
EXEC sp_configure 'xp_cmdshell', 0
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'show advanced options', 0
RECONFIGURE WITH OVERRIDE
END
END
GO
/****** Object: StoredProcedure [dbo].[utility_SPACE_GetLogSizeForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get database log size for each database
-- =============================================
create PROCEDURE [dbo].[utility_SPACE_GetLogSizeForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
--Displaying log space information for all databases
--The following example displays LOGSPACE information for all databases contained in the instance of SQL Server
DBCC SQLPERF(LOGSPACE);
END
GO
/****** Object: StoredProcedure [dbo].[utility_SPACE_GetSizeAtFileLevelForAllDatabase] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get database size for each database
-- =============================================
CREATE PROCEDURE [dbo].[utility_SPACE_GetSizeAtFileLevelForAllDatabase]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
-- Check to see the temp table exists
IF EXISTS ( SELECT name
FROM tempdb..sysobjects
WHERE name LIKE '#HoldforEachDBSize%' )
DROP TABLE #HoldforEachDBSize
CREATE TABLE #HoldforEachDBSize
(
DatabaseName NVARCHAR(75) NOT NULL,
Size DECIMAL NOT NULL,
Name NVARCHAR(75) NOT NULL,
Filename NVARCHAR(90) NOT NULL)
IF EXISTS ( SELECT name
FROM tempdb..sysobjects
WHERE name LIKE '#FixedDrives%' )
DROP TABLE #FixedDrives
CREATE TABLE #FixedDrives
(
Drive CHAR(1) NOT NULL,
MBFree DECIMAL NOT NULL)
-- Insert rows from sp_MSForEachDB into temp table
INSERT INTO #HoldforEachDBSize
EXEC sp_MSforeachdb 'SELECT ''?'' AS DatabaseName,
CASE WHEN [?]..sysfiles.size * 8 / 1024 = 0 THEN 1
ELSE [?]..sysfiles.size * 8 / 1024
END AS size,
[?]..sysfiles.name AS Name,
[?]..sysfiles.filename AS Filename
FROM [?]..sysfiles'
INSERT INTO #FixedDrives
EXEC xp_fixeddrives
SELECT RTRIM(CAST(DatabaseName AS VARCHAR(75))) AS DatabaseName,
Drive AS Drive,
Filename AS Filename,
CAST(Size AS INT) AS Size,
CAST(MBFree AS VARCHAR(10)) AS MB_Free
FROM #HoldforEachDBSize
INNER JOIN #FixedDrives ON LEFT(#HoldforEachDBSize.Filename, 1) = #FixedDrives.Drive
GROUP BY DatabaseName,
Drive,
MBFree,
Filename,
CAST(Size AS INT)
ORDER BY Drive,
Size DESC
SELECT Drive AS [Total Data Space Used],
CAST(SUM(Size) AS VARCHAR(10)) AS [Total Size],
CAST(MBFree AS VARCHAR(10)) AS MB_Free
FROM #HoldforEachDBSize
INNER JOIN #FixedDrives ON LEFT(#HoldforEachDBSize.Filename, 1) = #FixedDrives.Drive
GROUP BY Drive,
MBFree
SELECT COUNT(DISTINCT RTRIM(CAST(DatabaseName AS VARCHAR(75)))) AS Database_Count
FROM #HoldforEachDBSize
DROP TABLE #FixedDrives
DROP TABLE #HoldforEachDBSize
END
GO
/****** Object: StoredProcedure [dbo].[utility_SendInitDBEmail] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: In order to modify configure easily , we init sp_send_dbmail first
-- =============================================
CREATE PROCEDURE [dbo].[utility_SendInitDBEmail]
(
@p_Subject NVARCHAR(200),
@p_Body NVARCHAR(MAX)
)
AS
BEGIN
SET @p_Subject= '[SQL Auto Email - '+ @@SERVERNAME + '] - '+ISNULL(@p_Subject,'')
EXEC msdb.dbo.sp_send_dbmail @profile_name='Database Mail Public Profile',
@recipients = 'alex.tian@morningstar.com;jason.liu@morningstar.com;Kenny.Chen@morningstar.com',
@subject = @p_Subject,
@body = @p_Body,
@body_format = 'HTML'
END
GO
/****** Object: StoredProcedure [dbo].[utility_TEMPDB_GetTempdbSpaceInfo] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-01
-- Description: Get tempdb total space usage by object type
-- =============================================
CREATE PROCEDURE [dbo].[utility_TEMPDB_GetTempdbSpaceInfo]
AS
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT SUM (user_object_reserved_page_count) * (8.0/1024.0) AS [User Objects (MB)],
SUM (internal_object_reserved_page_count) * (8.0/1024.0) AS [Internal Objects (MB)],
SUM (version_store_reserved_page_count) * (8.0/1024.0) AS [Version Store (MB)],
SUM (mixed_extent_page_count)* (8.0/1024.0) AS [Mixed Extent (MB)],
SUM (unallocated_extent_page_count)* (8.0/1024.0) AS [Unallocated (MB)]
FROM sys.dm_db_file_space_usage
END
GO
/****** Object: UserDefinedFunction [dbo].[fn_FormatHtmlTable] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create FUNCTION [dbo].[fn_FormatHtmlTable]
(
@p_Html VARCHAR(MAX),
@p_HtmlHeader VARCHAR(MAX)
)
RETURNS VARCHAR(MAX) AS
BEGIN
DECLARE @l_CSS NVARCHAR(MAX)
DECLARE @l_Output VARCHAR(MAX)
SET @l_Output=''
SET @l_CSS= '<style type="text/css">
table.gridtable {
font-family: verdana,arial,sans-serif;
font-size:11px;
color:#333333;
border-width: 1px;
border-color: #666666;
border-collapse: collapse; }
table.gridtable th {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #dedede;}
table.gridtable td {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #ffffff;}
</style>'
SET @l_Output = @l_CSS + REPLACE(@p_Html,'<TABLE>' ,'<TABLE class="gridtable">' + @p_HtmlHeader)
RETURN @l_Output
END
GO
/****** Object: UserDefinedFunction [dbo].[fn_GetSQLBySPID] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-03
-- Description: Get sql scirpt by SPID
-- =============================================
CREATE FUNCTION [dbo].[fn_GetSQLBySPID]
(
@p_SPID INT
)
RETURNS VARCHAR(MAX) AS
BEGIN
DECLARE @l_Output VARCHAR(MAX)
SET @l_Output=''
DECLARE @sql_handle binary(20), @handle_found bit
DECLARE @stmt_start int, @stmt_end int
SELECT @sql_handle = sql_handle,
@stmt_start = stmt_start/2,
@stmt_end = CASE WHEN stmt_end = -1 THEN -1 ELSE stmt_end/2 END
FROM master.dbo.sysprocesses
WHERE spid = @p_SPID
AND ecid = 0
SET @l_Output = (SELECT SUBSTRING( text,
COALESCE(NULLIF(@stmt_start, 0), 1),
CASE @stmt_end WHEN -1 THEN DATALENGTH(text)
ELSE (@stmt_end - @stmt_start)
END)
FROM ::fn_get_sql(@sql_handle))
RETURN @l_Output
END
GO
/****** Object: UserDefinedFunction [dbo].[fn_SplitStringToHtmlHeader] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fn_SplitStringToHtmlHeader]
(
@p_Input VARCHAR(MAX),
@p_Delimeter CHAR(1) = ','
)
RETURNS VARCHAR(MAX) AS
BEGIN
DECLARE @l_Output VARCHAR(MAX)
SET @l_Output=''
SELECT @l_Output = @l_Output + '<TH>' + Value + '</TH>'
FROM dbo.fn_SplitStringToTable(@p_Input,',')
SET @l_Output = '<TR>' + @l_Output + '</TR>'
RETURN @l_Output
END
GO
/****** Object: UserDefinedFunction [dbo].[fn_SplitStringToQueryColumn] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-03
-- Description: split string to sql query column
-- =============================================
CREATE FUNCTION [dbo].[fn_SplitStringToQueryColumn]
(
@p_Input VARCHAR(MAX),
@p_Delimeter CHAR(1) = ','
)
RETURNS VARCHAR(MAX) AS
BEGIN
DECLARE @l_Output VARCHAR(MAX)
SET @l_Output=''
SELECT @l_Output = @l_Output + 'ISNULL(' + 'CAST(['+Value +'] AS NVARCHAR(MAX))' +' ,'''')' + ' AS TD, '
FROM dbo.fn_SplitStringToTable(@p_Input,',')
RETURN LEFT(@l_Output,LEN(@l_Output)-1)
END
GO
/****** Object: UserDefinedFunction [dbo].[fn_SplitStringToTable] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alex Tian
-- Create date: 2012-09-03
-- Description: split string as a table format
-- =============================================
CREATE FUNCTION [dbo].[fn_SplitStringToTable]
(
@p_Input VARCHAR(MAX),
@p_Delimeter CHAR(1) = ','
)
RETURNS @l_Table TABLE
(
Id INT IDENTITY(1, 1),
Value VARCHAR(511),
Position INT,
Length INT
)
BEGIN
DECLARE @l_Position INT,
@l_Value VARCHAR(256)
SELECT @l_Position = 1,
@l_Value = ''
IF RIGHT(@p_Input, LEN(@p_Delimeter)) <> @p_Delimeter
SET @p_Input = @p_Input + @p_Delimeter
WHILE SUBSTRING(@p_Input, @l_Position, 1) = CHAR(10) OR
SUBSTRING(@p_Input, @l_Position, 1) = CHAR(13)
BEGIN
SELECT @l_Position = @l_Position + 1
END
WHILE @l_Position <= CHARINDEX(@p_Delimeter, @p_Input, @l_Position)
BEGIN
SET @l_Value = RTRIM ( LTRIM ( SUBSTRING ( @p_Input,
@l_Position,
CHARINDEX ( @p_Delimeter,
@p_Input,
@l_Position) - @l_Position ) ) )
IF NOT EXISTS ( SELECT 1
FROM @l_Table
WHERE Value = @l_Value )
BEGIN
INSERT INTO @l_Table ( Value, Position, Length )
VALUES ( @l_Value, @l_Position, CHARINDEX ( @p_Delimeter,
@p_Input,
@l_Position ) - @l_Position )
END
SELECT @l_Position = CHARINDEX(@p_Delimeter, @p_Input, @l_Position) + 1
WHILE SUBSTRING(@p_Input, @l_Position, 1) = CHAR(10) OR
SUBSTRING(@p_Input, @l_Position, 1) = CHAR(13)
BEGIN
SELECT @l_Position = @l_Position + 1
END
END
RETURN
END
GO
/****** Object: Table [dbo].[AvailableDiskSpace] Script Date: 2012/9/7 9:36:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[AvailableDiskSpace](
[Id] [int] IDENTITY(1,1) NOT NULL,
[LastUpdate] [smalldatetime] NOT NULL,
[DriveLetter] [char](1) NOT NULL,
[FreeMB] [int] NOT NULL,
CONSTRAINT [PK_AvailableDiskSpace] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [NutsAndBolts_Data]
) ON [NutsAndBolts_Data]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[ErrorLog] Script Date: 2012/9/7 9:36:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[ErrorLog](
[Time] [datetime] NOT NULL,
[Err] [int] NOT NULL,
[Msg] [varchar](500) NOT NULL,
[Id] [varchar](50) NOT NULL,
[DBName] [varchar](30) NOT NULL,
[ProcName] [varchar](50) NOT NULL,
[DBUser] [varchar](20) NOT NULL,
[HostName] [varchar](20) NOT NULL,
[Application] [varchar](30) NOT NULL,
[Checked] [bit] NOT NULL
) ON [NutsAndBolts_Data]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[EventLog] Script Date: 2012/9/7 9:36:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[EventLog](
[Id] [int] IDENTITY(1,1) NOT NULL,
[EventData] [xml] NOT NULL,
CONSTRAINT [PK_EventLog] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [NutsAndBolts_Data]
) ON [NutsAndBolts_Data] TEXTIMAGE_ON [NutsAndBolts_Data]
GO
/****** Object: Table [dbo].[ProcUsage] Script Date: 2012/9/7 9:36:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[ProcUsage](
[TrackType] [tinyint] NULL,
[DBName] [varchar](30) NOT NULL,
[ProcName] [varchar](50) NOT NULL,
[Id] [varchar](15) NULL,
[LastAccess] [datetime] NOT NULL,
[AccessCount] [int] NOT NULL,
[DBUser] [varchar](20) NOT NULL,
[HostName] [varchar](20) NOT NULL,
[AppName] [varchar](50) NOT NULL,
[Checked] [bit] NOT NULL
) ON [NutsAndBolts_Data]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[AvailableDiskSpace] ADD CONSTRAINT [DF_AvailableDiskSpace_LastUpdate] DEFAULT (getdate()) FOR [LastUpdate]
GO
ALTER TABLE [dbo].[ErrorLog] ADD CONSTRAINT [DF_ErrorLog_Time] DEFAULT (getdate()) FOR [Time]
GO
ALTER TABLE [dbo].[ErrorLog] ADD CONSTRAINT [DF_ErrorLog_DBName] DEFAULT (left(db_name(),(30))) FOR [DBName]
GO
ALTER TABLE [dbo].[ErrorLog] ADD CONSTRAINT [DF_ErrorLog_DBUser] DEFAULT (left(suser_sname(),(20))) FOR [DBUser]
GO
ALTER TABLE [dbo].[ErrorLog] ADD CONSTRAINT [DF_ErrorLog_HostName] DEFAULT (left(host_name(),(20))) FOR [HostName]
GO
ALTER TABLE [dbo].[ErrorLog] ADD CONSTRAINT [DF_ErrorLog_Application] DEFAULT (left(rtrim(ltrim(app_name())),(30))) FOR [Application]
GO
ALTER TABLE [dbo].[ErrorLog] ADD CONSTRAINT [DF_ErrorLog_Checked] DEFAULT ((0)) FOR [Checked]
GO
ALTER TABLE [dbo].[ProcUsage] ADD CONSTRAINT [DF_ProcUsage_LastAccess] DEFAULT (getdate()) FOR [LastAccess]
GO
ALTER TABLE [dbo].[ProcUsage] ADD CONSTRAINT [DF_ProcUsage_AccessCount] DEFAULT ((1)) FOR [AccessCount]
GO
ALTER TABLE [dbo].[ProcUsage] ADD CONSTRAINT [DF_ProcUsage_DBUser] DEFAULT (left(rtrim(ltrim(suser_sname())),(20))) FOR [DBUser]
GO
ALTER TABLE [dbo].[ProcUsage] ADD CONSTRAINT [DF_ProcUsage_HostName] DEFAULT (left(rtrim(ltrim(host_name())),(20))) FOR [HostName]
GO
ALTER TABLE [dbo].[ProcUsage] ADD CONSTRAINT [DF_ProcUsage_AppName] DEFAULT (left(rtrim(ltrim(app_name())),(30))) FOR [AppName]
GO
ALTER TABLE [dbo].[ProcUsage] ADD CONSTRAINT [DF_ProcUsage_Checked] DEFAULT ((0)) FOR [Checked]
GO