带有 #tem_table 的对象名称无效

Invalid object name with #tem_table

我正在尝试执行查询以获取 highCpuUtilization 查询警报。如果我正在执行查询,它会显示结果。当我想使用 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 = 'con-balususr@mail.com',
@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 将 运行 在不同的上下文中,并且没有对您声明的临时 table.

的权限

改用全局临时 table (##PossibleCPUUtilizationQueries)。

正如 Aaron 非常正确地指出的那样,您也可以只使用永久 table 来存储数据,而不是使用临时 tables。

有关本地和全局临时 tables

的更多信息,请参阅 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.