#tem_table无效的对象名称

时间:2015-03-18 16:28:40

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

我正在尝试执行查询以获取highCpuUtilization查询警报。如果我正在执行查询,它会显示结果。当我想使用dbmail将结果发送到我的邮件时,它会抛出错误。

  

(3行受影响)

     

(1行受影响)

     

(1行受影响)

     

消息22050,级别16,状态1,行0可能是格式化查询错误   无效参数消息14661,级别16,状态1,过程   sp_send_dbmail,第517行查询执行失败:消息208,级别16,   状态1,服务器FSQADBTRVS \ FSQADBTR,第1行无效的对象名称   '#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

1 个答案:

答案 0 :(得分:2)

EXEC msdb.dbo.sp_send_dbmail将在不同的上下文中运行,并且对您声明的临时表没有权限。

改为使用全局临时表(##PossibleCPUUtilizationQueries)。

正如Aaron非常正确地指出你也可以使用永久表来存储数据而不是使用临时表。

有关本地和全局临时表的更多信息,请参阅here

  

临时表有两种类型:本地和全局。本地   临时表仅在其创建者期间可见   表格首次连接到SQL Server实例   创建或引用。在删除本地临时表后   用户断开与SQL Server实例的连接。全球临时   表对任何用户和任何连接都可见   创建,并在引用该表的所有用户时删除   断开与SQL Server实例的连接。