sql - #tem_table 的对象名称无效

标签 sql sql-server sql-server-2008 sql-server-2008-r2 sql-server-2012

我正在尝试执行查询以获得高 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/

相关文章:

sql - 错误 3265 - 记录集中存在字段

mysql - 获取重复的sql结果

sql - 用户定义函数 - Northwind 数据库 - Employee_Name 函数

mysql - 显示同一表的列中可以具有相同数据的表中的数据

sql-server - 分组SQL Server请求

sql-server - T-SQL 将带前导零的数字插入表中

sql - 只需在 SQL Server 的列上设置 DEFAULT 与设置 CONSTRAINT

mysql - group by 子句不分组

sql - 带有 many-ISNULL 的多列 UPDATE-JOIN 需要很长时间?

sql-server-2008 - 在 SQL Server 2008 中创建具有自动递增 ID 列的 View