我正在尝试执行查询以获得高 CpuUtilization 查询警报。如果我正在执行查询,它会显示结果。当我想使用 dbmail 将结果发送到我的邮件时,它抛出错误。
(3 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
Msg 22050, Level 16, State 1, Line 0 Error formatting query, probably invalid parameters Msg 14661, Level 16, State 1, Procedure sp_send_dbmail, Line 517 Query execution failed: Msg 208, Level 16, State 1, Server FSQADBTRVS\FSQADBTR, Line 1 Invalid object name '#PossibleCPUUtilizationQueries'.
这是我正在尝试运行的查询
DECLARE @ts_now bigint
DECLARE @SQLVersion decimal (4,2) -- 9.00, 10.00
DECLARE @AvgCPUUtilization DECIMAL(10,2)
SELECT @SQLVersion = LEFT(CAST(SERVERPROPERTY('PRODUCTVERSION') AS VARCHAR), 4) -- find the SQL Server Version
-- sys.dm_os_sys_info works differently in SQL Server 2005 vs SQL Server 2008+
-- comment out SQL Server 2005 if SQL Server 2008+
-- SQL Server 2005
--IF @SQLVersion = 9.00
--BEGIN
-- SELECT @ts_now = cpu_ticks / CONVERT(float, cpu_ticks_in_ms) FROM sys.dm_os_sys_info
--END
-- SQL Server 2008+
IF @SQLVersion >= 10.00
BEGIN
SELECT @ts_now = cpu_ticks/(cpu_ticks/ms_ticks) FROM sys.dm_os_sys_info
END
-- load the CPU utilization in the past 3 minutes into the temp table, you can load them into a permanent table
SELECT TOP(3) SQLProcessUtilization AS [SQLServerProcessCPUUtilization]
,SystemIdle AS [SystemIdleProcess]
,100 - SystemIdle - SQLProcessUtilization AS [OtherProcessCPU Utilization]
,DATEADD(ms, -1 * (@ts_now - [timestamp]), GETDATE()) AS [EventTime]
INTO #CPUUtilization
FROM (
SELECT record.value('(./Record/@id)[1]', 'int') AS record_id,
record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int')
AS [SystemIdle],
record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]',
'int')
AS [SQLProcessUtilization], [timestamp]
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 '%<SystemHealth>%') AS x
) AS y
ORDER BY record_id DESC
-- check if the average CPU utilization was over 90% in the past 2 minutes
SELECT @AvgCPUUtilization = AVG([SQLServerProcessCPUUtilization] + [OtherProcessCPU Utilization])
FROM #CPUUtilization
WHERE EventTime > DATEADD(MM, -2, GETDATE())
IF @AvgCPUUtilization >= 0
BEGIN
SELECT TOP(10)
CONVERT(VARCHAR(25),@AvgCPUUtilization) +'%' AS [AvgCPUUtilization]
, GETDATE() [Date and Time]
, r.cpu_time
, r.total_elapsed_time
, s.session_id
, s.login_name
, s.host_name
, DB_NAME(r.database_id) AS DatabaseName
, SUBSTRING (t.text,(r.statement_start_offset/2) + 1,
((CASE WHEN r.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), t.text)) * 2
ELSE r.statement_end_offset
END - r.statement_start_offset)/2) + 1) AS [IndividualQuery]
, SUBSTRING(text, 1, 200) AS [ParentQuery]
, r.status
, r.start_time
, r.wait_type
, s.program_name
INTO #PossibleCPUUtilizationQueries
FROM sys.dm_exec_sessions s
INNER JOIN sys.dm_exec_connections c ON s.session_id = c.session_id
INNER JOIN sys.dm_exec_requests r ON c.connection_id = r.connection_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE s.session_id > 50
AND r.session_id != @@spid
order by r.cpu_time desc
-- query the temp table, you can also send an email report
SELECT * FROM #PossibleCPUUtilizationQueries
END
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'Databasemail',
@recipients = '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e0838f8ecd82818c9593959392a08d81898cce838f8d" rel="noreferrer noopener nofollow">[email protected]</a>',
@query = 'SELECT * FROM #PossibleCPUUtilizationQueries',
@subject = 'Work Order Count',
@attach_query_result_as_file = 1 ;
-- drop the temp tables
IF OBJECT_ID('TEMPDB..#CPUUtilization') IS NOT NULL
drop table #CPUUtilization
IF OBJECT_ID('TEMPDB..#PossibleCPUUtilizationQueries') IS NOT NULL
drop table #PossibleCPUUtilizationQueries
最佳答案
EXEC msdb.dbo.sp_send_dbmail
将在不同的上下文中运行,并且对您声明的临时表没有权限。
改用全局临时表 (##PossibleCPUUtilizationQueries
)。
正如 Aaron 非常正确地指出的那样,您也可以只使用永久表来存储数据,而不是使用临时表。
参见here有关本地和全局临时表的更多信息
There are two types of temporary tables: local and global. Local temporary tables are visible only to their creators during the same connection to an instance of SQL Server as when the tables were first created or referenced. Local temporary tables are deleted after the user disconnects from the instance of SQL Server. Global temporary tables are visible to any user and any connection after they are created, and are deleted when all users that are referencing the table disconnect from the instance of SQL Server.
关于sql - #tem_table 的对象名称无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29127474/