Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como faço para capturar os dados passados ​​no SqlBulkCopy usando o Sql Profiler?


Capturando informações de eventos para operações de inserção em massa ( BCP.EXE , SqlBulkCopy , e presumo que BULK INSERT e OPENROWSET(BULK... ) é possível, mas você não poderá ver as linhas e colunas individuais.

As operações de inserção em massa aparecem como uma única instrução DML (bem, uma por lote, e o padrão é fazer todas as linhas em um único lote) de:
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

Você pode encontrar a lista completa de "dicas" na página do MSDN para o BCP Utilitário . Observe que SqlBulkCopy suporta apenas um subconjunto dessas dicas (por exemplo, KEEP_NULLS , TABLOCK , e alguns outros), mas não suporte ORDER(...) ou ROWS_PER_BATCH= (o que é muito lamentável, na verdade, já que o ORDER() dica é necessária para evitar uma classificação que acontece no tempdb para permitir que a operação seja minimamente registrada (assumindo que as outras condições para tal operação também foram satisfeitas).

Para ver essa instrução, você precisa capturar qualquer um dos seguintes eventos no SQL Server Profiler:

Você também desejará selecionar, pelo menos, as seguintes colunas (no SQL Server Profiler):

E, como um usuário não pode enviar um INSERT BULK declaração diretamente, você provavelmente pode filtrar isso em Filtros de Coluna se quiser apenas ver esses eventos e nada mais.

Se você quiser ver a notificação oficial de que um BULK INSERT operação está começando e/ou terminando, então você precisa capturar o seguinte evento:

e, em seguida, adicione as seguintes colunas do Profiler:

Para ObjectName você sempre obterá eventos mostrando "BULK INSERT" e se isso está começando ou terminando é determinado pelo valor em EventSubClass , que é "0 - Begin" ou "1 - Commit" (e suponho que, se falhar, você verá "2 - Rollback").

Se o ORDER() dica não foi especificada (e novamente, não pode ser especificado ao usar SqlBulkCopy ), você também receberá um evento "SQLTransaction" mostrando "sort_init" no ObjectName coluna. Este evento também tem eventos "0 - Begin" e "1 - Commit" (como mostrado no EventSubClass coluna).

Por fim, mesmo que você não possa ver as linhas específicas, ainda poderá ver as operações no log de transações (por exemplo, inserir linha, modificar linha do IAM, modificar linha PFS etc.) se capturar o seguinte evento:

e adicione a seguinte coluna Profiler:

As principais informações de interesse estarão na EventSubClass coluna, mas infelizmente são apenas valores de ID e não consegui encontrar nenhuma tradução desses valores na documentação do MSDN. No entanto, encontrei a seguinte postagem no blog de Jonathan Kehayias:Usando eventos estendidos no SQL Server Denali CTP1 para mapear o evento TransactionLog SQL Trace Valores EventSubClass .

@RBarryYoung apontou que os valores e nomes de EventSubClass podem ser encontrados em sys.trace_subclass_values exibição de catálogo, mas consultar essa exibição mostra que ela não tem linhas para o 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 :(

Observe que o SqlBulkCopy.BatchSize propriedade é equivalente a definir o -b opção para BCP.EXE , que é uma configuração operacional que controla como cada comando dividirá as linhas em conjuntos. Isso não é o mesmo que o ROWS_PER_BATCH= dica que não controla fisicamente como as linhas são divididas em conjuntos, mas permite que o SQL Server planeje melhor como alocará as páginas e, portanto, reduz o número de entradas no log de transações (às vezes um pouco). Ainda assim, meus testes mostraram que:
  • especificando -b para BCP.EXE definiu o ROWS_PER_BATCH= dica para esse mesmo valor.
  • especificando o SqlBulkCopy.BatchSize propriedade não defina o ROWS_PER_BATCH= dica, MAS, o benefício da atividade reduzida do log de transações estava definitivamente lá (mágica?). O fato de que o efeito líquido é ainda obter o benefício é o motivo pelo qual eu não o mencionei no topo quando disse que era lamentável que o ORDER() dica não era suportada por SqlBulkCopy .