我一直在使用Sql Profiler来捕获SQL语句并重新运行有问题的语句。非常有用。
但是,有些代码使用SqlBulkCopy API,我不知道如何捕获它们。我看到临时表的创建,但没有任何填充它们。似乎SqlBulkCopy绕过了Sql Profiler,或者我没有捕获正确的事件。
答案 0 :(得分:8)
捕获批量插入操作的事件信息(BCP.EXE
,SqlBulkCopy
,我认为BULK INSERT
和OPENROWSET(BULK...
)是可能的,但您不会成为能够看到各个行和列。
批量插入操作显示为单个(好,每个批次一个,默认是在一个批次中执行所有行)DML语句:
INSERT BULK <destination_table_name> (
<column1_name> <column1_datatype> [ COLLATE <column1_collation> ], ...
) [ WITH (<1 or more hints>) ]
<hints> := KEEP_NULLS, TABLOCK, ORDER(...), ROWS_PER_BATCH=, etc
您可以找到&#34;提示&#34;的完整列表。在BCP Utility的MSDN页面上。请注意,SqlBulkCopy仅支持这些提示的子集(例如KEEP_NULLS
,TABLOCK
和其他一些提示),但不支持ORDER(...)
或{{1 } ** (实际上,这是非常不幸的,因为需要ROWS_PER_BATCH=
提示以避免在tempdb中发生的排序以便允许最小程度地记录操作(假设此类操作的其他条件也已得到满足。)
要查看此语句,您需要捕获SQL Server Profiler中的以下任何事件:
SQL:BatchStarting
SQL:BatchCompleted
SQL:StmtStarting
SQL:StmtCompleted事件
您还希望至少选择以下列(在SQL Server Profiler中):
的TextData
CPU
读取
写
持续时间
SPID
开始时间
结束时间
RowCounts
而且,由于用户无法直接提交ORDER()
语句,如果您只想查看这些事件而不是其他任何内容,则可以在列过滤器中对其进行过滤。
如果您想查看INSERT BULK
操作开始和/或结束的正式通知,则需要捕获以下事件:
的SqlTransaction
然后添加以下Profiler列:
EventSubClass
的ObjectName
对于BULK INSERT
,您将始终获得显示&#34; BULK INSERT&#34;以及是开始还是结束是由ObjectName
中的值决定的,它是&#34; 0 - 开始&#34;或&#34; 1 - 提交&#34; (我想如果它失败了你应该看到&#34; 2 - 回滚&#34;)。
如果未指定EventSubClass
提示(并且再次使用ORDER()
时无法指定),那么您还将获得&#34; SQLTransaction&# 34;事件显示&#34; sort_init&#34;在SqlBulkCopy
列中。这个事件也有&#34; 0 - 开始&#34;和&#34; 1 - 提交&#34;事件(如ObjectName
列中所示)。
最后,即使您看不到特定的行,如果捕获以下事件,仍然可以看到针对事务日志的操作(例如插入行,修改IAM行,修改PFS行等):
TransactionLog
并添加以下Profiler列:
的ObjectID
感兴趣的主要信息将在EventSubClass
列中,但遗憾的是它只是ID值,我在MSDN文档中找不到这些值的任何翻译。但是,我确实找到了Jonathan Kehayias的以下博文:Using Extended Events in SQL Server Denali CTP1 to Map out the TransactionLog SQL Trace Event EventSubClass Values。
@RBarryYoung指出可以在EventSubClass
目录视图中找到EventSubClass值和名称,但查询该视图显示它没有sys.trace_subclass_values
事件的行:
TransactionLog
** 请注意,SELECT * FROM sys.trace_categories -- 12 = Transactions
SELECT * FROM sys.trace_events WHERE category_id = 12 -- 54 = TransactionLog
SELECT * FROM sys.trace_subclass_values WHERE trace_event_id = 54 -- nothing :(
属性相当于为 BCP.EXE 设置SqlBulkCopy.BatchSize
选项,这是一项操作设置它控制每个命令如何将行分解为集合。这与-b
提示不同,后者没有物理控制行如何分解成集,而是允许SQL Server更好地规划它将如何分配页面,从而减少了条目的数量。事务日志(有时相当多)。我的测试仍显示:
ROWS_PER_BATCH=
确实将-b
提示设置为相同的值。ROWS_PER_BATCH=
属性不设置SqlBulkCopy.BatchSize
提示,但是,减少事务日志活动的好处肯定存在(魔术?)。事实上净效应仍然可以获益,这就是为什么当我说ROWS_PER_BATCH=
不支持ORDER()
提示是不幸的时候我没有提到它的原因。答案 1 :(得分:0)
您无法在SQL事件探查器中捕获SqlBulkCopy
,因为在SQL Server表中插入数据时,SqlBulkCopy
根本不会生成SQL。 SqlBulkCopy
的工作方式类似于bcp
实用程序,并将数据直接加载到SQL Server文件系统中。插入行时甚至是can ignore FKs and triggers!