Używamy CDC do przechwytywania zmian wprowadzonych w tabeli produkcyjnej. Zmienione wiersze są eksportowane do hurtowni danych (informatica). Wiem, że kolumna __ $ update_mask przechowuje, które kolumny zostały zaktualizowane w formie varbinary. Wiem też, że mogę użyć różnych funkcji CDC, aby dowiedzieć się z tej maski, jakie były te kolumny.
Moje pytanie brzmi: Czy ktoś może dla mnie zdefiniować logikę tej maski, abyśmy mogli zidentyfikować kolumny, które zostały zmienione w magazynie? Ponieważ przetwarzamy poza serwerem, nie mamy łatwego dostępu do funkcji MSCQL CDC. Wolę po prostu sam rozbić maskę w kodzie. Wydajność funkcji cdc po stronie SQL jest problematyczna dla tego rozwiązania.
Krótko mówiąc, chciałbym ręcznie zidentyfikować zmienione kolumny w polu __ $ update_mask.
Aktualizacja:
Dopuszczalne było również przesłanie do magazynu czytelnej dla człowieka listy zmienionych kolumn. Odkryliśmy, że można tego dokonać przy wydajności znacznie większej niż nasze pierwotne podejście.
Odpowiedź CLR na to pytanie poniżej spełnia tę alternatywę i zawiera szczegóły dotyczące interpretacji maski dla przyszłych gości. Jednak zaakceptowana odpowiedź przy użyciu XML PATH jest najszybsza z dotychczasowych dla tego samego wyniku końcowego.
źródło
Odpowiedzi:
Morał tej historii jest… testuj, próbuj innych rzeczy, myśl duży, potem mały, zawsze zakładaj, że jest lepszy sposób.
Ciekawe naukowo, jak moja ostatnia odpowiedź. Postanowiłem wypróbować jeszcze jedno podejście. Przypomniałem sobie, że mogę połączyć sztuczkę XML PATH (''). Ponieważ wiedziałem, jak uzyskać porządek każdej zmienionej kolumny z listy captured_column z poprzedniej odpowiedzi, pomyślałem, że warto przetestować, czy funkcja bitu MS działałaby lepiej w taki sposób, jak tego potrzebowaliśmy.
Jest o wiele czystszy niż (choć nie tak zabawny jak) cały ten CLR, zwraca to podejście tylko do natywnego kodu SQL. I rolka bębna .... zwraca te same wyniki w mniej niż sekundę . Ponieważ dane produkcyjne są 100 razy większe, liczy się każda sekunda.
Pozostawiam drugą odpowiedź do celów naukowych - ale na razie jest to nasza poprawna odpowiedź.
źródło
Po kilku badaniach postanowiliśmy jednak zrobić to po stronie SQL przed przekazaniem do hurtowni danych. Ale przyjmujemy to znacznie ulepszone podejście (w oparciu o nasze potrzeby i nowe zrozumienie działania maski).
Za pomocą tego zapytania otrzymujemy listę nazw kolumn i ich porządkowe pozycje. Zwrot powraca w formacie XML, dzięki czemu możemy przekazać do SQL CLR.
Następnie przekazujemy ten blok XML jako zmienną i pole maski do funkcji CLR, która zwraca łańcuch rozdzielany przecinkami kolumn, które zmieniły się zgodnie z polem binarnym _ $ update_mask. Ta funkcja clr sprawdza pole maski w celu zmiany bitu dla każdej kolumny na liście xml, a następnie zwraca jej nazwę z odpowiedniej porządkowej.
Kod c # clr wygląda następująco: (skompilowany w zestawie o nazwie CDCUtilities)
I funkcja CLR wygląda następująco:
Następnie dołączamy tę listę kolumn do zestawu wierszy i przekazujemy do hurtowni danych do analizy. Używając zapytania i clr, unikamy konieczności używania dwóch wywołań funkcji na wiersz na zmianę. Możemy przejść bezpośrednio do mięsa z wynikami dostosowanymi do naszego wystąpienia przechwytywania zmian.
Dzięki temu postowi przepełnienia stosu zaproponowanemu przez Jona Seigela dla sposobu interpretacji maski.
Z naszego doświadczenia wynika, że jesteśmy w stanie uzyskać listę wszystkich zmienionych kolumn z 10k wierszy cdc w mniej niż 3 sekundy.
źródło