I am using Sql Profiler all the time to capture the SQL statements and rerun problematic ones. Very useful.
However, some code uses the SqlBulkCopy API and I have no idea how to capture those. I see creation of temp tables, but nothing that populates them. Seems like SqlBulkCopy bypasses Sql Profiler or I do not capture the right events.
Capturing event info for bulk insert operations (
BCP.EXE
,SqlBulkCopy
, and I assumeBULK INSERT
, andOPENROWSET(BULK...
) is possible, but you won't be able to see the individual rows and columns.Bulk Insert operations show up as a single (well, one per batch, and the default is to do all rows in a single batch) DML statement of:
You can find the full list of "hints" on the MSDN page for the BCP Utility. Please note that SqlBulkCopy only supports a subset of those hints (e.g.
KEEP_NULLS
,TABLOCK
, and a few others) but does not supportORDER(...)
orROWS_PER_BATCH=
** (which is quite unfortunate, actually, as theORDER()
hint is needed in order to avoid a sort that happens in tempdb in order to allow the operation to be minimally logged (assuming the other conditions for such an operation have also been satisfied).In order to see this statement, you need to capture any of the following events in SQL Server Profiler:
You will also want to select, at least, the following columns (in SQL Server Profiler):
And, since a user cannot submit an
INSERT BULK
statement directly, you can probably filter on that in Column Filters if you merely want to see these events and nothing else.If you want to see the official notification that a
BULK INSERT
operation is beginning and/or ending, then you need to capture the following event:and then add the following Profiler columns:
For
ObjectName
you will always get events showing "BULK INSERT" and whether that is beginning or ending is determined by the value inEventSubClass
, which is either "0 - Begin" or "1 - Commit" (and I suppose if it fails you should see "2 - Rollback").If the
ORDER()
hint was not specified (and again, it cannot be specified when usingSqlBulkCopy
), then you will also get a "SQLTransaction" event showing "sort_init" in theObjectName
column. This event also has "0 - Begin" and "1 - Commit" events (as shown in theEventSubClass
column).Finally, even though you cannot see the specific rows, you can still see operations against the Transaction Log (e.g. insert row, modify IAM row, modify PFS row, etc) if you capture the following event:
and add the following Profiler column:
The main info of interest will be in the
EventSubClass
column, but unfortunately it is just ID values and I could not find any translation of those values in MSDN documentation. However, I did find the following blog post by Jonathan Kehayias: Using Extended Events in SQL Server Denali CTP1 to Map out the TransactionLog SQL Trace Event EventSubClass Values.@RBarryYoung pointed out that EventSubClass values and names can be found in the
sys.trace_subclass_values
catalog view, but querying that view shows that it has no rows for theTransactionLog
event:** Please note that the
SqlBulkCopy.BatchSize
property is equivalent to setting the-b
option for BCP.EXE, which is an operational setting that controls how each command will break up the rows into sets. This is not the same as theROWS_PER_BATCH=
hint which does not physically control how the rows are broken up into sets, but instead allows SQL Server to better plan how it will allocate pages, and hence reduces the number of entries in the Transaction Log (sometimes by quite a bit). Still my testing showed that:-b
for BCP.EXE did set theROWS_PER_BATCH=
hint to that same value.SqlBulkCopy.BatchSize
property did not set theROWS_PER_BATCH=
hint, BUT, the benefit of reduced Transaction Log activity was somehow definitely there (magic?). The fact that the net effect is to still gain the benefit is why I did not mention it towards the top when I said that it was unfortunate that theORDER()
hint was not supported bySqlBulkCopy
.You cann't capture
SqlBulkCopy
in SQL Profiler becauseSqlBulkCopy
doesn't generate SQL at all when inserts data in SQL Server table.SqlBulkCopy
works similar tobcp
utility and loads data directly into SQL Server file system. It's even can ignore FKs and triggers when inserts the rows!