Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Logowanie operacji aktualizacji w wyzwalaczach

Zanim odpowiem, pozwól mi najpierw powiedzieć, że nie sądzę, aby logować wszystkie stoły do ​​jednej tabeli. Jeśli twoja baza danych się rozrośnie, możesz skończyć z poważną rywalizacją o tabelę Log. Ponadto wszystkie dane muszą zostać zmienione na varchar lub sql_variant, aby zostały umieszczone w tej samej kolumnie, co zmusza je do zajęcia większej ilości miejsca. Myślę też, że rejestrowanie każdej zaktualizowanej kolumny w osobnym wierszu (pomijanie kolumn, które nie są aktualizowane) sprawi, że będzie bardzo trudne do zapytania. Czy wiesz, jak zebrać wszystkie te dane, aby faktycznie uzyskać złożony i rozsądny widok zmian w każdym wierszu, kiedy i przez kogo? Moim zdaniem posiadanie jednej tabeli logarytmicznej na stół będzie znacznie łatwiejsze. Wtedy nie będziesz mieć problemów, których doświadczasz, próbując je uruchomić.

Czy wiesz również o SQL Server 2008 Zmień przechwytywanie danych ? Użyj tego zamiast, jeśli używasz wersji Enterprise lub Developer SQL Server!

Oprócz tego możesz robić, co chcesz, za pomocą logicznego UNPIVOT (wykonując własną wersję). Nie możesz tak naprawdę użyć UNPIVOT natywnego SQL 2005, ponieważ masz dwie kolumny docelowe, a nie jedną. Oto przykład dla SQL Server 2005 i nowszych przy użyciu CROSS APPLY do wykonania UNPIVOT:

INSERT INTO dbo.LOG (Id_Table, Table_Key_Value, Id_Value, Old_Value, New_Value)
SELECT 12345, I.Id, X.Id_Value, X.Old_Value, X.New_Value
FROM
   INSERTED I 
   INNER JOIN DELETED D ON I.ID = D.ID
   CROSS APPLY (
      SELECT 4556645, D.Name, I.Name
      UNION ALL SELECT 544589, D.Surname, I.Surname
    ) X (Id_Value, Old_Value, New_Value)
WHERE
   X.Old_Value <> X.New_Value

Oto bardziej ogólna metoda dla SQL 2000 lub innych DBMS (teoretycznie powinna działać w Oracle, MySQL itp. -- dla Oracle dodaj FROM DUAL do każdego SELECT w tabeli pochodnej):

INSERT INTO dbo.LOG (Id_Table, Table_Key_Value, Id_Value, Old_Value, New_Value)
SELECT *
FROM (
   SELECT
      12345,
      I.Id,
      X.Id_Value,
      CASE X.Id_Value
         WHEN 4556645 THEN D.Name
         WHEN 544589 THEN D.Surname
      END Old_Value,
      CASE X.Id_Value
         WHEN 4556645 THEN I.Name
         WHEN 544589 THEN I.Surname
      END New_Value   
   FROM
      INSERTED I 
      INNER JOIN DELETED D ON I.ID = D.ID
      CROSS JOIN (
         SELECT 4556645
         UNION ALL SELECT 544589
      ) X (Id_Value)
) Y
WHERE
   Y.Old_Value <> Y.New_Value

SQL Server 2005 i nowsze mają natywne polecenie UNPIVOT, chociaż ogólnie, nawet jeśli UNPIVOT będzie działać, lubię zamiast tego używać CROSS APPLY, ponieważ zapewniam większą elastyczność w robieniu tego, co chcę. W szczególności natywne polecenie UNPIVOT nie działa tutaj, ponieważ UNPIVOT może kierować tylko do jednej kolumny docelowej, ale potrzebujesz dwóch (Stara_Wartość, Nowa_Wartość). Łączenie dwóch kolumn w jedną wartość (i późniejsze rozdzielanie) nie jest dobre; tworzenie bezsensownej wartości korelatora wierszy do PIVOT z później nie jest dobre i nie mogę wymyślić innego sposobu na zrobienie tego, który nie jest odmianą tych dwóch. Rozwiązanie CROSS APPLY będzie naprawdę najlepsze, aby dopasować dokładną strukturę tabeli logów, którą opisałeś.

W porównaniu do moich zapytań tutaj, metoda nr 1 nie będzie działać tak dobrze (w stosunku około {liczba kolumn}:1 gorsza wydajność). Twoja metoda nr 2 jest dobrym pomysłem, ale nadal nieoptymalna, ponieważ wywołanie UDF wiąże się z dużym obciążeniem, a ponadto musisz zapętlić każdy wiersz (drżenie).




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Maksymalny rozmiar wiersza programu SQL Server w porównaniu z rozmiarem Varchar (maksymalny)

  2. Jak znaleźć nazwę serwera dla SQL Server 2005

  3. Jak przekonwertować ciąg DateTime na DateTime w SQL Server

  4. SQL Server 2012:suma nad zamówieniem przez daje błąd Niepoprawna składnia w pobliżu „zamówienie”

  5. Zatrzymaj dostęp przed używaniem niewłaściwej tożsamości podczas dołączania do tabeli połączonej na serwerze SQL