Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Регистриране на операция за актуализиране в тригери

Преди да отговоря, позволете ми първо да кажа, че не мисля, че е най-добре да записвам всички таблици в една таблица. Ако вашата база данни се разрасне, може да се окажете със сериозна конкуренция в таблицата на журнала. Освен това всичките ви данни трябва да бъдат променени на varchar или sql_variant, за да бъдат поставени в същата колона, принуждавайки ги да заемат повече място. Също така мисля, че регистрирането на всяка актуализирана колона в отделен ред (пропускане на колони, които не са актуализирани) ще го направи много трудно за вас да попитате. Знаете ли как да съберете всички тези данни заедно, за да получите всъщност съставен и разумен изглед на промените на всеки ред, кога и от кого? Според мен ще бъде много по-лесно да имаш една таблица с журнали на таблица. Тогава няма да имате проблемите, които изпитвате, опитвайки се да го накарате да работи.

Освен това знаете ли за SQL Server 2008 Промяна на записа на данни ? Използвайте го вместо това, ако използвате изданията Enterprise или Developer на SQL Server!

Освен този проблем, можете да правите каквото искате с логически UNPIVOT (изпълнявайки своя собствена негова версия). Не можете наистина да използвате Native SQL 2005 UNPIVOT, защото имате две целеви колони, а не една. Ето пример за SQL Server 2005 и по-нова версия, използвайки CROSS APPLY за извършване на 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

Ето един по-общ метод за SQL 2000 или други СУБД (теоретично трябва да работи в Oracle, MySQL и т.н. -- за Oracle добавете FROM DUAL към всеки SELECT в извлечената таблица):

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 и по-нови имат собствената команда UNPIVOT, но като цяло, дори когато UNPIVOT работи, ми харесва да използвам CROSS APPLY вместо това, защото има повече гъвкавост да правя това, което искам. По-конкретно, собствената команда UNPIVOT не е работеща тук, защото UNPIVOT може да насочва само към една колона местоназначение, но имате нужда от две (Old_Value, New_Value). Свързването на двете колони в една стойност (и разделянето по-късно) не е добро; създаването на безсмислена стойност на корелатор на ред към PIVOT след това не е добро и не мога да измисля друг начин да го направя, който да не е вариация на тези два. Решението CROSS APPLY наистина ще бъде най-доброто за вас, за да съответства на точната структура на регистрационната таблица, която сте описали.

В сравнение с моите заявки тук, вашият метод №1 няма да се представи толкова добре (в съотношение около {броя на колоните}:1 по-лоша производителност). Вашият метод #2 е добра идея, но все още е неоптимален, защото извикването на UDF има голямо натоварване, освен това трябва да преминавате през всеки ред (потръпване).




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 3 начина да получите стъпките за работа на работа за агент на SQL Server (T-SQL)

  2. SQL Database Mirroring и вашето уеб приложение

  3. Добавете колони към съществуваща таблица в базата данни на SQL Server

  4. Как мога да задам израз на свойството FileSpec на Foreach File enumerator?

  5. Изберете данни от XML файл като таблица в TSQL