#sql-server #triggers
Вопрос:
Мне нравится подавать таблицу журнала изменений с помощью триггера обновления. Программное обеспечение, использующее таблицу, может изменять дизайн таблицы. Поэтому мне нравится сравнивать старое значение с новым, столбец за столбцом, сравнивая вставленные и удаленные. Если есть разница, необходимо записать запись в журнале. К сожалению, я не нашел решения для получения значения вставленной, удаленной таблицы по имени столбца @col курсора. Я попробовал несколько вещей с EXEC, но в этом контексте вставка недоступна.
Как я могу получить доступ к значению столбца вставлено, удалено с помощью общего кода?
Я был бы очень рад, если бы кто-нибудь мог мне помочь.
Овации
Таблица LAG_Artikel_Log:
CREATE TABLE [dbo].[LAG_Artikel_Log](
[LaufNr] [int] IDENTITY(1,1) NOT NULL,
[ArtikelNrLAG] [varchar](50) NOT NULL,
[ErstelltAm] [datetime] NOT NULL,
[ErstelltVon] [varchar](30) NULL,
[EigenschaftName] [varchar](256) NULL,
[EigenschaftWertAlt] [varchar](256) NULL,
[EigenschaftWertNeu] [varchar](256) NULL,
Спусковой крючок:
ALTER TRIGGER [dbo].[Update_LAG_Artikel_Log]
ON [dbo].[LAG_Artikel] AFTER UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
-- Insert statements for trigger here--------------------------------------------------------------------------------------------------
DECLARE @col VARCHAR(128)
DECLARE @tableName VARCHAR(128)
SET @tableName = 'LAG_Artikel'
DECLARE cursor_col CURSOR
FOR SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS AS ic
WHERE ic.TABLE_NAME = @tableName
OPEN cursor_col
FETCH NEXT FROM cursor_col INTO @col
WHILE @@FETCH_STATUS = 0
BEGIN
IF inserted.@col != deleted.@col
BEGIN
----------------------------if not same ------------------------------------------------------------------------------------
INSERT INTO LAG_Artikel_Log(ArtikelNrLAG, ErstelltAm, ErstelltVon, EigenschaftName, EigenschaftWertNeu, EigenschaftWertAlt)
SELECT i.ArtikelNrLAG, SYSDATETIME(), i.ErstelltVon, @col, , i.@col , d.@col
FROM inserted AS i
INNER JOIN deleted AS d ON i.ArtikelNrLAG = d.ArtikelNrLAG
END
FETCH NEXT FROM cursor_col INTO @col
END
CLOSE cursor_col
DEALLOCATE cursor_col
END
Комментарии:
1. Это ужасный дизайн! Вам необходимо использовать динамический sql для построения правильного оператора, считывая столбцы из information_schema. Этот триггер будет узким местом производительности, курсор и несколько вставок будут выполняться как часть транзакции, выполняющей обновление, что снижает ее производительность и параллелизм.
2. Есть ли лучшая идея, как реализовать журнал изменений для динамически меняющейся таблицы?
3. Динамически меняющаяся таблица звучит как антипаттерн, является ли реляционная база данных правильным инструментом для этой работы?
4. динамически изменяемая таблица -вот ваша настоящая проблема. Таблицы представляют реальные вещи и редко должны меняться. И когда они действительно меняются, подавляющему большинству других систем требуется анализ воздействия и обновления других зависимых частей вашей «системы», чтобы убедиться, что все продолжает работать правильно. И это
IF inserted.@col != deleted.@col
просто неверный синтаксис — для этого вам понадобится динамический sql. Я также должен добавить, что триггер должен обрабатывать несколько строк во вставленных / удаленных таблицах. Не предполагайте, что существует одна строка.5.
IF inserted.@col != deleted.@col
состоит в том, чтобы показать желаемую функциональность. Я попытался использовать sp с динамически генерируемыми запросами. К сожалению, тип возвращаемого значения будет изменяться, и вставленные удаленные таблицы неизвестны в выполняемом sp. Я не могу изменить логику программы, которая изменяет таблицы.