SELECT sp_WhoIsActive 变成 Table

SELECT sp_WhoIsActive into Table

我正在尝试将 sp_WhoIsActive 编写成 table。目标是每 10 秒向 table 提供一个代理作业。

我关注了 this guide 并尝试以这种方式喂 table:

--Log activity into table.  
DECLARE @destination_table VARCHAR(4000) = 
  '[Monitoring].[dbo].[WhoIsActive] ' 
  
EXEC sp_WhoIsActive
  @get_plans = 1, 
  @get_transaction_info = 1, 
  @destination_table = @destination_table;

但结果我收到错误:

Warning: The join order has been enforced because a local join hint is used.
Msg 50000, Level 16, State 1, Procedure sp_WhoIsActive, Line 1111 [Batch Start Line 0]
Destination table not properly formatted.

在 Google 上,我发现许多指南都在谈论一种解决方案,可以帮助我将存储过程执行到临时 table 中,然后我可以从那里创建一个 table:

sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO

SELECT * INTO #MyTempTable FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;',
   'EXEC sp_WhoIsActive')

SELECT * FROM #MyTempTable

但此过程也失败并出现错误:

Msg 11526, Level 16, State 1, Procedure sys.sp_describe_first_result_set, Line 1 [Batch Start Line 12]
The metadata could not be determined because statement 'INSERT #sessions
        (
            recursion,
            session_id,
            request_id' in procedure 'sp_WhoIsActive' uses a temp table.

我尝试关注 Kendra Little blog,但那也行不通。

最后我手动编写了 table 脚本:

CREATE TABLE [dbo].[WhoIsActive](
    [dd_hh_mm_ss_mss] [nvarchar](50) NOT NULL,
    [session_id] [tinyint] NOT NULL,
    [sql_text] [nvarchar](max) NOT NULL,
    [sql_command] [nvarchar](400) NOT NULL,
    [login_name] [nvarchar](50) NOT NULL,
    [wait_info] [nvarchar](50) NOT NULL,
    [tran_log_writes] [nvarchar](50) NOT NULL,
    [CPU] [smallint] NOT NULL,
    [tempdb_allocations] [smallint] NOT NULL,
    [tempdb_current] [smallint] NOT NULL,
    [blocking_session_id] [nvarchar](50) NOT NULL,
    [reads] [int] NOT NULL,
    [writes] [float] NOT NULL,
    [physical_reads] [tinyint] NOT NULL,
    [query_plan] [nvarchar](50) NOT NULL,
    [used_memory] [tinyint] NOT NULL,
    [status] [nvarchar](50) NOT NULL,
    [tran_start_time] [datetime2](7) NOT NULL,
    [implicit_tran] [nvarchar](50) NOT NULL,
    [open_tran_count] [tinyint] NOT NULL,
    [percent_complete] [nvarchar](50) NOT NULL,
    [host_name] [nvarchar](50) NOT NULL,
    [database_name] [nvarchar](50) NOT NULL,
    [program_name] [nvarchar](100) NOT NULL,
    [start_time] [datetime2](7) NOT NULL,
    [login_tine] [datetime2](7) NOT NULL,
    [request_id] [tinyint] NOT NULL,
    [collection_time] [datetime2](7) NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

但那也失败了,我无法为 table 提供一份工作。

sp_WhoIsActive 如此受欢迎,我不敢相信我是唯一一个试图将结果插入 table.

的人

您需要创建一个 table suitable 以与过程的输出一起使用,其架构可能因您使用的选项而异。

SP_WhoIsActive 实际上会为您提供 create 脚本,因此要捕获默认选项只需执行

declare @definition varchar(max)
exec sp_WhoIsActive @return_schema = 1, @schema = @definition output
print @definition

这个returns合适T-SQL:

CREATE TABLE < table_name > (
    [dd hh:mm:ss.mss] VARCHAR(8000) NULL
    ,[session_id] SMALLINT NOT NULL
    ,[sql_text] XML NULL
    ,[login_name] NVARCHAR(128) NOT NULL
    ,[wait_info] NVARCHAR(4000) NULL
    ,[CPU] VARCHAR(30) NULL
    ,[tempdb_allocations] VARCHAR(30) NULL
    ,[tempdb_current] VARCHAR(30) NULL
    ,[blocking_session_id] SMALLINT NULL
    ,[reads] VARCHAR(30) NULL
    ,[writes] VARCHAR(30) NULL
    ,[physical_reads] VARCHAR(30) NULL
    ,[used_memory] VARCHAR(30) NULL
    ,[status] VARCHAR(30) NOT NULL
    ,[open_tran_count] VARCHAR(30) NULL
    ,[percent_complete] VARCHAR(30) NULL
    ,[host_name] NVARCHAR(128) NULL
    ,[database_name] NVARCHAR(128) NULL
    ,[program_name] NVARCHAR(128) NULL
    ,[start_time] DATETIME NOT NULL
    ,[login_time] DATETIME NULL
    ,[request_id] INT NULL
    ,[collection_time] DATETIME NOT NULL
    )

使用所需的目标 table 名称编辑和 运行,然后您可以 运行 sp_whoisactive 使用目标 table 选项

exec sp_WhoIsActive @destination_table='Monitoring.dbo.WhoIsActive'

See the docs