1

出于监控和调查目的,我希望将结果sp_WhoIsActive(尤其是 xml 列的查询计划)存储到表中,由于限制,我必须将结果存储在另一台服务器上。

使用链接服务器尝试此操作时,错误弹出:

分布式查询不支持 XML 数据类型。远程对象“IROWSET”具有 xml 列

如何做到这一点?

4

3 回答 3

3

首先,您需要获取参数的架构,如下所示:

DECLARE @createTableSchema VARCHAR(MAX) 
EXEC sp_WhoIsActive
    @filter = '',
    @filter_type = 'session',
    @not_filter = '',
    @not_filter_type = 'session',
    @show_own_spid = 0,
    @show_system_spids = 0,
    @show_sleeping_spids = 0,
    @get_full_inner_text = 0,
    @get_plans = 1,
    @get_outer_command = 0,
    @get_transaction_info = 1,
    @get_task_info = 1,
    @get_locks = 0,
    @get_avg_time = 0,
    @get_additional_info = 1,
    @find_block_leaders = 0,
    @delta_interval = 0,
    @output_column_list = '[dd%][session_id][sql_text][sql_command][login_name][wait_info][tasks][tran_log%][cpu%][temp%][block%][reads%][writes%][context%][physical%][query_plan][locks][%]',
    @sort_order = '[start_time] ASC',
    @format_output = 1,
    @destination_table = '',
    @return_schema = 1,
    @schema = @createTableSchema OUTPUT,
    @help = 0;
SELECT @createTableSchema
GO 

获得架构后,使用它来创建表,如下所示:

CREATE TABLE dbo.AuditTableName (
    [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
    ,[tran_log_writes] 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
    ,[query_plan] XML NULL
    ,[used_memory] VARCHAR(30) NULL
    ,[status] VARCHAR(30) NOT NULL
    ,[tran_start_time] DATETIME 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
    ,[additional_info] XML NULL
    ,[start_time] DATETIME NOT NULL
    ,[login_time] DATETIME NULL
    ,[request_id] INT NULL
    ,[collection_time] DATETIME NOT NULL
    )

现在,在 sp_whoisactive 调用中提及 Audit 表名称。sp_whoisactive 中的数据将存储在表中。

EXEC sp_WhoIsActive
    @filter = '',
    @filter_type = 'session',
    @not_filter = '',
    @not_filter_type = 'session',
    @show_own_spid = 0,
    @show_system_spids = 0,
    @show_sleeping_spids = 0,
    @get_full_inner_text = 0,
    @get_plans = 1,
    @get_outer_command = 0,
    @get_transaction_info = 1,
    @get_task_info = 1,
    @get_locks = 0,
    @get_avg_time = 0,
    @get_additional_info = 1,
    @find_block_leaders = 0,
    @delta_interval = 0,
    @output_column_list = '[dd%][session_id][sql_text][sql_command][login_name][wait_info][tasks][tran_log%][cpu%][temp%][block%][reads%][writes%][context%][physical%][query_plan][locks][%]',
    @sort_order = '[start_time] ASC',
    @format_output = 1,
    @destination_table = 'dbo.AuditTableName',
    @return_schema = 0,
    @schema = NULL,
    @help = 0;
GO 

您也可以参考 Adam Mechanic 本人的详细文章。捕获 Whoisactive 的输出

于 2017-08-24T21:17:48.743 回答
0

Brent Ozar 有一个颜色很好的例子,位于这里。查看第一步以创建目标表。

然而,Adam Machanic在这里找到了一个更详细的示例,我相信他编写了这个出色的诊断过程并将其发布给公众。谢谢亚当!

基本上你必须使用参数@return_schema=1 和@schema 作为输出变量。之后,您使用您选择的表格替换 ''。然后将其作为动态 SQL 执行。

于 2013-11-14T11:51:03.800 回答
0

看起来您有一堆 SQL 服务器,并希望将所有结果发送到一个中央全局生产审计服务器。这是我用过的方法。这允许您添加其他列,例如 SERVER NAME。Linked Servers 根本不支持 XML 数据类型,它必须是一个小的修改解决方案。

您必须将 XML 列转换为 aVARCHAR(MAX)并将查询计划作为 a 存储VARCHAR(MAX)在其他服务器的全局表中。执行以下步骤

  1. 使用带有 XML 列<table>的架构创建一个sp_WhoIsActive
  2. 运行INSERT INTO <table>... EXEC sp_WhoIsActive以在一个语句中填充该表
  3. 现在查询<table>将 XML 转换为VARCHAR(MAX)
  4. 将转换后的 XML 的结果插入到VARCHAR链接服务器的表中
  5. 在 SQL 代理作业中执行此操作也可以。
于 2014-08-29T19:09:04.420 回答