sql >> Databasteknik >  >> RDS >> Sqlserver

Hur fångar jag in data som skickas i SqlBulkCopy med hjälp av Sql Profiler?

Fångar händelseinformation för massinsättningsoperationer ( BCP.EXE , SqlBulkCopy , och jag antar BULK INSERT och OPENROWSET(BULK... ) är möjligt, men du kommer inte att kunna se de enskilda raderna och kolumnerna.

Bulk Insert-operationer visas som en enda (nåja, en per batch, och standarden är att göra alla rader i en enda batch) DML-sats av:

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

Du kan hitta hela listan med "tips" på MSDN-sidan för BCP Verktyg . Observera att SqlBulkCopy endast stöder en delmängd av dessa tips (t.ex. KEEP_NULLS , TABLOCK , och några andra) men gör det inte stödja ORDER(...) eller ROWS_PER_BATCH= (vilket faktiskt är ganska olyckligt, eftersom ORDER() ledtråd behövs för att undvika en sortering som händer i tempdb för att tillåta operationen att loggas minimalt (förutsatt att övriga villkor för en sådan operation också är uppfyllda).

För att se detta uttalande måste du fånga någon av följande händelser i SQL Server Profiler:

Du kommer också att vilja välja, åtminstone, följande kolumner (i SQL Server Profiler):

Och eftersom en användare inte kan skicka en INSERT BULK uttalande direkt, du kan förmodligen filtrera på det i kolumnfilter om du bara vill se dessa händelser och inget annat.

Om du vill se det officiella meddelandet att en BULK INSERT operationen börjar och/eller slutar, då måste du fånga följande händelse:

och lägg sedan till följande Profiler-kolumner:

För ObjectName du kommer alltid att få händelser som visar "BULK INSERT" och om det börjar eller slutar bestäms av värdet i EventSubClass , vilket är antingen "0 - Start" eller "1 - Commit" (och jag antar att om det misslyckas bör du se "2 - Rollback").

Om ORDER() ledtråd specificerades inte (och återigen, det kan inte). anges när du använder SqlBulkCopy ), kommer du också att få en "SQLTransaction"-händelse som visar "sort_init" i ObjectName kolumn. Denna händelse har även "0 - Begin" och "1 - Commit"-händelser (som visas i EventSubClass kolumn).

Slutligen, även om du inte kan se de specifika raderna, kan du fortfarande se operationer mot transaktionsloggen (t.ex. infoga rad, ändra IAM-rad, ändra PFS-rad, etc) om du fångar följande händelse:

och lägg till följande Profiler-kolumn:

Huvudinformationen av intresse kommer att finnas i EventSubClass kolumn, men tyvärr är det bara ID-värden och jag kunde inte hitta någon översättning av dessa värden i MSDN-dokumentationen. Däremot hittade jag följande blogginlägg av Jonathan Kehayias:Använda utökade händelser i SQL Server Denali CTP1 för att kartlägga TransactionLog SQL Trace Event EventSubClass-värden .

@RBarryYoung påpekade att EventSubClass-värden och -namn kan hittas i sys.trace_subclass_values katalogvy, men att fråga den vyn visar att den inte har några rader för TransactionLog händelse:

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 :(

Observera att SqlBulkCopy.BatchSize egenskap motsvarar inställning av -b alternativ för BCP.EXE , som är en operativ inställning som styr hur varje kommando delar upp raderna i uppsättningar. Detta är inte detsamma som ROWS_PER_BATCH= ledtråd som inte fysiskt styr hur raderna delas upp i uppsättningar, utan istället tillåter SQL Server att bättre planera hur den ska allokera sidor, och därmed minskar antalet poster i transaktionsloggen (ibland med en hel del). Mina tester visade fortfarande att:

  • specificerar -b för BCP.EXE ställde in ROWS_PER_BATCH= antyda samma värde.
  • ange SqlBulkCopy.BatchSize egendom inte ställ in ROWS_PER_BATCH= tips, MEN fördelen med minskad transaktionsloggaktivitet fanns på något sätt definitivt där (magi?). Det faktum att nettoeffekten är att fortfarande vinna fördelen är varför jag inte nämnde det högst upp när jag sa att det var olyckligt att ORDER() tipset stöddes inte av SqlBulkCopy .


  1. Hur man delar MySQL-tabellposter på mitten för att visas på varje sida av en sida

  2. I mysql, visar databaserna; kommandot listar inte alla mina databaser

  3. Visa aktuell användares data och dess namn i den valda taggen

  4. Kontrollera om databasen redan finns