5

Cały czas używam Sql Profiler do przechwytywania instrukcji SQL i ponownego uruchamiania problematycznych. Bardzo przydatne.Jak przechwycić dane przekazane w SqlBulkCopy za pomocą Sql Profiler?

Jednak niektóre kod wykorzystuje API SqlBulkCopy i nie mam pojęcia, w jaki sposób, aby uchwycić te. Widzę tworzenie tabel tymczasowych, ale nic, co je zapełnia. Wygląda na to, że SqlBulkCopy omija Sql Profiler lub nie przechwytuję właściwych zdarzeń.

Każda pomoc jest doceniana.

+0

Czy Twoje tagi są prawidłowe? Czy jest to pytanie związane z MySQL? –

+0

Oczywiście, że nie. Popełniłem błąd. Głupi ja. To jest serwer Sql. Dziękuję Ci. – mark

+0

Czy próbujesz przechwycić zapytanie, aby uzyskać dane lub wstawić dane? –

Odpowiedz

0

Nie można przechwycić SqlBulkCopy w programie SQL Profiler, ponieważ SqlBulkCopy nie generuje w ogóle SQL podczas wstawiania danych do tabeli programu SQL Server. SqlBulkCopy działa podobnie do narzędzia bcp i ładuje dane bezpośrednio do systemu plików SQL Server. Jest nawet can ignore FKs and triggers podczas wstawiania wierszy!

+2

Odnośnie "' SqlBulkCopy' nie generuje w ogóle SQL podczas wstawiania danych w tabeli SQL Server. ": To absolutnie nie jest prawdą. Generuje on instrukcję INSERT, którą można zobaczyć w programie SQL Server Profiler. Jest to operacja 'insert bulk'. Nie można ominąć programu SQL Server w celu wprowadzenia danych do bazy danych. Gdyby to było możliwe, to unieważniłoby zgodność ACID. Cytat z odpowiedzi forum MSDN jest poza kontekstem i wprowadza w błąd. Osoba twierdziła, że ​​zapytanie SELECT nie może być odróżniane od wszystkich innych zapytań jako _definitely_ od BCP. –

+0

@ śrutzky dzięki, usunąłem ten mylący cytat. To moja wina, zapomniałem o słowie 'insert bulk'. Jednak to stwierdzenie wydaje się być bezużyteczne - nie zawiera danych, tylko schemat tabeli docelowej (czy znowu się mylę?). Ponadto, dlaczego nie zamieściłeś odpowiedzi zamiast komentarza? –

+0

Cześć. Nie dodałem odpowiedzi, ponieważ czekałem na wyjaśnienia z PO, które dodałem teraz :) –

6

Przechwytywanie informacji zdarzeń dla masowych operacji INSERT (BCP.EXE, SqlBulkCopy, i zakładam BULK INSERT i OPENROWSET(BULK...) jest możliwe, ale nie będzie mógł zobaczyć poszczególne wiersze i kolumny.

Operacje zbiorcze Wstaw pokazać się jako singiel (dobrze, po jednej partii, a wartość domyślna to zrobić wszystkie wiersze w jednej partii) oświadczenie DML z:

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 

można znaleźć pełną listę "podpowiedzi" na stronie MSDN dla BCP Utility. Należy pamiętać, że SqlBulkCopy obsługuje tylko podzbiór tych wskazówek (np , TABLOCK i kilku innych), ale robi nie wsparcie ORDER(...) lub ROWS_PER_BATCH=** (co jest dość niefortunne, rzeczywiście, jako wskazówkę ORDER() jest potrzebny aby uniknąć sortowania, które ma miejsce w tempdb, aby umożliwić minimalną rejestrację operacji (zakładając spełnienie innych warunków dla tej operacji)

Aby zobaczyć to stwierdzenie, musisz uchwycić każdą operację z następujących zdarzeń w SQL Server Profiler:

SQL: BatchStarting
SQL: BatchCompleted
SQL: StmtStarting
SQL: StmtCompleted

Będziesz także chcą, aby wybrać, co najmniej, następujące kolumny (SQL Server Profiler):

TextData
CPU
Odsłon
Zapisuje
Czas trwania
SPID
startTime
EndTime
RowCounts

A ponieważ użytkownik nie może złożyć oświadczenie INSERT BULK bezpośrednio, prawdopodobnie można filtrować że w filtrze kolumny jeśli tylko chcą zobaczyć te wydarzenia i nic więcej.

Jeśli chcesz zobaczyć oficjalne zawiadomienie, że operacja BULK INSERT jest początkiem i/lub końcowy, a następnie trzeba zarejestrować następujące zdarzenie:

SqlTransaction

a następnie dodać następujące kolumny Profiler:

EventSubClass
ObjectName

Dla ObjectName zawsze możesz liczyć wydarzenia wykazujące „BULK INSERT” i czy zaczyna się lub kończącym jest określana przez wartość w EventSubClass, który jest albo „0 - Rozpocznij” lub „1 - Commit” (i ja załóżmy, że jeśli się nie powiedzie, powinieneś zobaczyć "2 - Cofanie").

Jeśli wskazówka ORDER() nie został określony (i znowu, to niemoże być określona przy użyciu SqlBulkCopy), a następnie będzie można również uzyskać „SqlTransaction” wydarzenie pokazujące „sort_init” w kolumnie ObjectName. To zdarzenie ma również zdarzenia "0 - Rozpocznij" i "1 - Zatwierdź" (jak pokazano w kolumnie EventSubClass).

Wreszcie, choć nie widać konkretnych wierszy, nadal można zobaczyć operacje przeciwko dziennik transakcji (np wkładka rząd, modyfikować IAM wiersz, modyfikować PFS wiersz, etc), jeśli uchwycić następujące zdarzenie:

TransactionLog

i dodać po kolumnie Profiler:

ObjectID

Główne interesujące informacje będą w kolumnie EventSubClass, ale niestety są to tylko wartości ID i nie mogłem znaleźć żadnego tłumaczenia tych wartości w dokumentacji MSDN. Jednak znalazłem następujący wpis na blogu Jonathana Kehayiasa: Using Extended Events in SQL Server Denali CTP1 to Map out the TransactionLog SQL Trace Event EventSubClass Values.

@RBarryYoung podkreślić, że wartości EventSubClass i nazwy można znaleźć w widoku sys.trace_subclass_values katalogowej, ale odpytywanie ten pogląd pokazuje, że nie ma wierszy dla przypadku 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 :(

** Należy pamiętać, że właściwość SqlBulkCopy.BatchSize jest równoważna ustawieniu opcji dla BCP.EXE, która jest ustawieniem operacyjnym określającym sposób podziału wierszy przez każde polecenie w zestawy. To nie jest to samo, co podpowiedź ROWS_PER_BATCH=, która nie kontroluje fizycznie sposobu podziału wierszy na zestawy, ale zamiast tego pozwala programowi SQL Server lepiej planować sposób alokowania stron, a tym samym zmniejsza liczbę wpisów w dzienniku transakcji (czasami całkiem sporo). Nadal mój badania wykazały, że:

  • podając -b dla BCP.EXE ustawił podpowiedź ROWS_PER_BATCH= na tę samą wartość.
  • określając właściwość SqlBulkCopy.BatchSize podała nie ustawić podpowiedź ROWS_PER_BATCH=, ale korzyści z obniżonej aktywności dziennika transakcji było jakoś tam zdecydowanie (magia?). Fakt, że efekt netto ma nadal przynosić korzyści, to dlatego, że nie wspomniałem o tym na wierzchu, gdy powiedziałem, że to niefortunne, że podpowiedź ORDER() nie była obsługiwana przez SqlBulkCopy.
+0

Nie jest BatchSize, https://msdn.microsoft.com/en-us/library/system.data.sqlclient .sqlbulkcopy.batchsize (v = vs.110) .aspx, odpowiednik ROWS_PER_BATCH? –

+0

@ BruceDunwiddie Nie. Właściwość 'SqlBulkCopy.BatchSize' jest równoważna ustawieniu opcji' -b' dla BCP, chociaż właśnie zobaczyłem w śladzie Profiler, że BCP użyje tej wartości do ustawienia 'ROWS_PER_BATCH ='. Ale ustawienie 'BatchSize' dla SqlBulkCopy nie _nie_ ustawia wskazówki' ROWS_PER_BATCH = '. Ale ustawienie tej właściwości powoduje, że nadal, w jakiś sposób, pozwala zwiększyć wydajność. Dodam to wyjaśnienie do odpowiedzi. –

+0

IIRC, możesz tłumaczyć EventSubClass z widokiem katalogu 'sys.trace_subclass_values'. – RBarryYoung