У меня есть таблица в базе данных SQL Server 2005 с триггером, который должен добавить запись в другую таблицу при каждой вставке новой записи. Кажется, это работает нормально, но если я выполню команду Вставить в в основной таблице, которая использует подзапрос в качестве источника значений, триггер вставляет только одну запись в другую таблицу, даже если в основную запись было добавлено несколько записей. Я хочу, чтобы триггер срабатывал для каждой новой записи, добавленной в основную таблицу. Это возможно в 2005 году?
Вставка, которую я делаю:
INSERT INTO [tblMenuItems] ([ID], [MenuID], [SortOrder], [ItemReference], [MenuReference], [ConcurrencyID]) SELECT [ID], [MenuID], [SortOrder], [ItemReference], [MenuReference], [ConcurrencyID] FROM [IVEEtblMenuItems]
Вот как выглядит триггер:
CREATE TRIGGER [dbo].[tblMenuItemInsertSecurity] ON [dbo].[tblMenuItems]
FOR INSERT
AS
Declare @iRoleID int
Declare @iMenuItemID int
Select @iMenuItemID = [ID] from Inserted
DECLARE tblUserRoles CURSOR FASTFORWARD FOR SELECT [ID] from tblUserRoles
OPEN tblUserRoles
FETCH NEXT FROM tblUserRoles INTO @iRoleID
WHILE (@@FetchStatus = 0)
BEGIN
INSERT INTO tblRestrictedMenuItems(
[RoleID],
[MenuItemID],
[RestrictLevel])
VALUES(
@iRoleID,
@iMenuItemID,
1)
FETCH NEXT FROM tblUserRoles INTO @iRoleID
END
CLOSE tblUserRoles
Deallocate tblUserRoles
Ваш триггер использует только первую строку из «Вставлено». Это распространенное недоразумение при работе с триггерами SQL впервые. Триггер срабатывает при обновлении, а не в строке.
Например, если вы делаете следующее: -
обновить набор продуктов title = 'geoff de geoff'
это обновит все продукты, но триггер на таблице продуктов будет срабатывать только один раз.
Вставленная «таблица», которую вы получите в триггере, будет содержать все строки. Вы должны либо выполнить цикл Inserted с курсором, либо лучше присоединить Inserted к таблице, которую вы обновляете.
Триггер срабатывает только один раз для каждой выполненной инструкции INSERT, а не один раз для каждой вставленной записи.
В вашем триггере вы можете получить доступ к «виртуальной» таблице, называемой вставкой, для получения подробной информации о вставленных записях.
то есть:
SELECT COUNT(*) FROM inserted
Вернет количество вставленных записей.
Посмотрите, пожалуйста, рассмотрение нескольких строк для триггеров. Что с курсором внутри триггера? Узнайте, как программировать наборы на основе, курсоры являются злыми в T-SQL и должны использоваться только для дефрагментации / обновления статистики / другого обслуживания множества таблиц
Я просто хочу поддержать @Gordon Bell в ответе ...
«Поймать» значения в тот момент, когда они вставляются. Вам не нужен курсор в этой ситуации (или, может быть, у вас есть причина?).
Вам может понадобиться простой TRIGGER:
http://dbalink.wordpress.com/2008/06/20/how-to-sql-server-trigger-101/