доступ вставлен, удален, жерно нажимает на триггер

#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. Я не могу изменить логику программы, которая изменяет таблицы.