Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come posso acquisire i dati passati in SqlBulkCopy usando Sql Profiler?

Acquisizione delle informazioni sull'evento per le operazioni di inserimento in blocco ( BCP.EXE , SqlBulkCopy , e presumo BULK INSERT e OPENROWSET(BULK... ) è possibile, ma non potrai vedere le singole righe e colonne.

Le operazioni di inserimento in blocco vengono visualizzate come un'unica istruzione DML (beh, una per batch e l'impostazione predefinita è di eseguire tutte le righe in un unico batch) di:

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

È possibile trovare l'elenco completo dei "suggerimenti" nella pagina MSDN per il BCP Utilità . Tieni presente che SqlBulkCopy supporta solo un sottoinsieme di tali suggerimenti (ad es. KEEP_NULLS , TABLOCK e pochi altri) ma non supporto ORDER(...) o ROWS_PER_BATCH= (che è piuttosto sfortunato, in realtà, come ORDER() hint è necessario per evitare un ordinamento che si verifica in tempdb in modo da consentire la registrazione minima dell'operazione (supponendo che anche le altre condizioni per tale operazione siano state soddisfatte).

Per visualizzare questa istruzione, è necessario acquisire uno dei seguenti eventi in SQL Server Profiler:

Dovrai anche selezionare almeno le seguenti colonne (in SQL Server Profiler):

E poiché un utente non può inviare un INSERT BULK direttamente, puoi probabilmente filtrarlo in Filtri colonna se vuoi semplicemente vedere questi eventi e nient'altro.

Se vuoi vedere la notifica ufficiale che un BULK INSERT l'operazione sta iniziando e/o finendo, quindi è necessario acquisire il seguente evento:

e quindi aggiungi le seguenti colonne Profiler:

Per ObjectName otterrai sempre eventi che mostrano "BULK INSERT" e se l'inizio o la fine è determinato dal valore in EventSubClass , che può essere "0 - Begin" o "1 - Commit" (e suppongo che se fallisce dovresti vedere "2 - Rollback").

Se il ORDER() il suggerimento non è stato specificato (e ancora, non può essere specificato quando si utilizza SqlBulkCopy ), otterrai anche un evento "SQLTransaction" che mostra "sort_init" in ObjectName colonna. Questo evento ha anche eventi "0 - Begin" e "1 - Commit" (come mostrato in EventSubClass colonna).

Infine, anche se non è possibile visualizzare le righe specifiche, è comunque possibile visualizzare le operazioni sul registro delle transazioni (ad es. inserire riga, modificare riga IAM, modificare riga PFS, ecc.) se si acquisisce il seguente evento:

e aggiungi la seguente colonna Profiler:

Le informazioni principali di interesse saranno nella EventSubClass colonna, ma sfortunatamente sono solo valori ID e non sono riuscito a trovare alcuna traduzione di quei valori nella documentazione MSDN. Tuttavia, ho trovato il seguente post sul blog di Jonathan Kehayias:Uso di eventi estesi in SQL Server Denali CTP1 per mappare l'evento di traccia SQL TransactionLog Valori EventSubClass .

@RBarryYoung ha sottolineato che i valori e i nomi di EventSubClass possono essere trovati in sys.trace_subclass_values vista del catalogo, ma l'interrogazione di tale vista mostra che non ha righe per il TransactionLog evento:

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

Si noti che il SqlBulkCopy.BatchSize è equivalente all'impostazione di -b opzione per BCP.EXE , che è un'impostazione operativa che controlla il modo in cui ogni comando suddividerà le righe in insiemi. Questo non è lo stesso di ROWS_PER_BATCH= suggerimento che non controlla fisicamente il modo in cui le righe vengono suddivise in set, ma consente invece a SQL Server di pianificare meglio come allocare le pagine e quindi riduce il numero di voci nel registro delle transazioni (a volte di parecchio). Tuttavia i miei test hanno dimostrato che:

  • specificando -b per BCP.EXE ha impostato il ROWS_PER_BATCH= suggerire lo stesso valore.
  • specificando il SqlBulkCopy.BatchSize proprietà non imposta il ROWS_PER_BATCH= suggerimento, MA, il vantaggio di una ridotta attività del registro delle transazioni era in qualche modo sicuramente lì (magia?). Il fatto che l'effetto netto sia quello di ottenere ancora il vantaggio è il motivo per cui non l'ho menzionato verso l'alto quando ho detto che era un peccato che ORDER() suggerimento non è stato supportato da SqlBulkCopy .