Я новичок в написании триггеров SQL Server. У меня есть таблица под названием USERS
, а также еще одна сделанная мной запись: USERS_DELTA
. Разница между двумя: USERS_DELTA
имеет один дополнительный столбец под названием change_type
.Триггер INSERT, вызывающий проблемы
Вот схема таблицы:
USERS
стол:
CREATE TABLE [dbo].[TDR_Users]
(
[objectGUID] [varbinary](50) NOT NULL,
[distinguishedName] [nvarchar](255) NOT NULL,
[adForest] [nvarchar](50) NULL,
[adDomain] [nvarchar](50) NULL,
[accountExpires] [datetime] NULL,
[adminCount] [int] NULL,
[cn] [nvarchar](64) NULL,
[company] [nvarchar](64) NULL,
[description] [nvarchar](448) NULL,
[displayName] [nvarchar](256) NULL,
[division] [nvarchar](256) NULL,
[employeeID] [nvarchar](16) NULL
)
И USERS_DELTA
стол:
CREATE TABLE [dbo].[TDR_Users]
(
[objectGUID] [varbinary](50) NOT NULL,
[distinguishedName] [nvarchar](255) NOT NULL,
[adForest] [nvarchar](50) NULL,
[adDomain] [nvarchar](50) NULL,
[accountExpires] [datetime] NULL,
[adminCount] [int] NULL,
[cn] [nvarchar](64) NULL,
[company] [nvarchar](64) NULL,
[description] [nvarchar](448) NULL,
[displayName] [nvarchar](256) NULL,
[division] [nvarchar](256) NULL,
[employeeID] [nvarchar](16) NULL,
[change_Type] [nvarchar](10) NULL
)
У меня есть приложение, которое будет создавать записи в таблице USERS
. Но то, что я пытаюсь сделать, это захватить вставки в USERS_DELTA
. Я написал триггер на USERS
таблице:
CREATE TRIGGER [dbo].[TR_INSERTS_DELTAS]
ON [dbo].[Users]
FOR INSERT
AS
DECLARE @ObjectGUID varbinary(50), @DN varchar(255), @memcount int;
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Get the primary and unique keys from the inserted rows.
SELECT @DN=i.distinguishedName FROM inserted i;
SELECT @ObjectGUID = i.objectGUID FROM inserted i;
-- Check if a row already exists in the TDR_Users_Delta table with those values.
SELECT @memcount=COUNT(*) FROM Users
WHERE Users.distinguishedName = @DN
AND Users.objectGUID = @ObjectGUID ;
if(@memcount = 0)
BEGIN
INSERT INTO [dbo].[Users_Delta]
(
[objectGUID],
[distinguishedName],
[adForest],
[adDomain],
[accountExpires],
[adminCount],
[cn] ,
[company],
[description],
[displayName],
[division],
[employeeID],
[change_type]
)
VALUES
(
INSERTED.[objectGUID],
INSERTED.[distinguishedName],
INSERTED.[adForest],
INSERTED.[adDomain],
INSERTED.[accountExpires],
INSERTED.[adminCount],
INSERTED.[cn] ,
INSERTED.[company],
INSERTED.[description],
INSERTED.[displayName],
INSERTED.[division],
INSERTED.[employeeID],
'Add'
);
END
END
GO
Когда я выполняю этот триггер, я получаю следующее сообщение об ошибке:
Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 94
The multi-part identifier "Inserted.objectGUID" could not be bound.Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 95
The multi-part identifier "INSERTED.distinguishedName" could not be bound.Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 96
The multi-part identifier "INSERTED.adForest" could not be bound.Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 97
The multi-part identifier "INSERTED.adDomain" could not be bound.Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 98
...
Что я делаю неправильно? :(
Просьба игнорировать имя в схеме таблицы. Я знаю, что говорит TDR_USERS Я уже исправил его на своем конце, но ошибка все еще сохраняется. Подумайте о чем-то в коде триггера. – user5078178
У вашего триггера есть ** ОСНОВНАЯ ** ошибка в том, что вы, кажется, предполагаете, что она будет называться ** один раз за строка ** - это ** не ** случай. Триггер будет срабатывать ** один раз за оператор **, поэтому, если ваши инструкции 'INSERT' влияют на 25 строк, вы получите триггер, запускаемый ** один раз **, но тогда 'Inserted' будет содержать 25 строк. Какая из этих 25 строк выберете здесь ваш код? SELECT @ DN = i.distinguish edName FROM вставил i; '- он не детерминирован - вы получите одну строку и проигнорируете все 24 других! Для этого нужно переписать триггер! –
Сделать комментарий marc_s другим способом. Подумайте, что таблица истории не является дельта-таблицей. Поэтому всегда добавляйте строку при каждом изменении. Это означает, что для таблицы истории потребуется другой первичный ключ, такой как идентификатор сотрудника и дата изменения GetDate(). Вам никогда не понадобится знать первичный ключ заранее в концепции таблицы истории. Все мои самые лучшие и самые длительные и самые стабильные проекты с базой данных с самым высоким уровнем имеют нулевые триггеры в них. –