SQL Server 2005 триггер вставки не вставляет достаточно записей - PullRequest
2 голосов
/ 20 августа 2008

У меня есть таблица в базе данных 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

Ответы [ 4 ]

3 голосов
/ 20 августа 2008

Ваш триггер использует только первую строку из «Вставлено». Это распространенное недоразумение при работе с триггерами SQL впервые. Триггер срабатывает при обновлении, а не в строке.

Например, если вы делаете следующее: -

обновление продуктов set title = 'geoff de geoff'

это обновит все продукты, но триггер на таблице продуктов будет срабатывать только один раз.

Вставленная «таблица», которую вы получите в триггере, будет содержать все строки. Вы должны либо выполнить цикл Inserted с курсором, либо лучше присоединить Inserted к таблице, которую вы обновляете.

2 голосов
/ 20 августа 2008

Пожалуйста, ищите рассмотрение нескольких строк для триггеров Что с курсором внутри триггера? Узнайте, как программировать наборы на основе, курсоры имеют зло в T-SQL и должны использоваться только для дефрагментации / обновления статистики / другого обслуживания множества таблиц

1 голос
/ 20 августа 2008

Триггер срабатывает только один раз для каждой выполненной инструкции INSERT, а не один раз для каждой вставленной записи.

В вашем триггере вы можете получить доступ к «виртуальной» таблице с именем вставлено для получения подробной информации о вставленных записях.

есть:

SELECT COUNT(*) FROM inserted 

Вернет количество вставленных записей.

0 голосов
/ 22 октября 2008

Я просто хочу второй @Гордон Белл на его ответ ...

«Поймать» значения в тот момент, когда они вставляются. Вам не нужен курсор в этой ситуации (или, может быть, у вас есть причина?).

Простой TRIGGER - это все, что вам нужно:

http://dbalink.wordpress.com/2008/06/20/how-to-sql-server-trigger-101/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...