出于监控和调查目的,我希望将结果sp_WhoIsActive
(尤其是 xml 列的查询计划)存储到表中,由于限制,我必须将结果存储在另一台服务器上。
使用链接服务器尝试此操作时,错误弹出:
分布式查询不支持 XML 数据类型。远程对象“IROWSET”具有 xml 列
如何做到这一点?
出于监控和调查目的,我希望将结果sp_WhoIsActive
(尤其是 xml 列的查询计划)存储到表中,由于限制,我必须将结果存储在另一台服务器上。
使用链接服务器尝试此操作时,错误弹出:
分布式查询不支持 XML 数据类型。远程对象“IROWSET”具有 xml 列
如何做到这一点?
首先,您需要获取参数的架构,如下所示:
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 的输出
Brent Ozar 有一个颜色很好的例子,位于这里。查看第一步以创建目标表。
然而,Adam Machanic在这里找到了一个更详细的示例,我相信他编写了这个出色的诊断过程并将其发布给公众。谢谢亚当!
基本上你必须使用参数@return_schema=1 和@schema 作为输出变量。之后,您使用您选择的表格替换 ''。然后将其作为动态 SQL 执行。
看起来您有一堆 SQL 服务器,并希望将所有结果发送到一个中央全局生产审计服务器。这是我用过的方法。这允许您添加其他列,例如 SERVER NAME。Linked Servers 根本不支持 XML 数据类型,它必须是一个小的修改解决方案。
您必须将 XML 列转换为 aVARCHAR(MAX)
并将查询计划作为 a 存储VARCHAR(MAX)
在其他服务器的全局表中。执行以下步骤
<table>
的架构创建一个sp_WhoIsActive
INSERT INTO <table>... EXEC sp_WhoIsActive
以在一个语句中填充该表<table>
将 XML 转换为VARCHAR(MAX)
VARCHAR
链接服务器的表中