SQL Server 2008 - Помогите написать простой триггер INSERT

Это с Microsoft SQL Server 2008.

У меня есть 2 таблицы, Employee и EmployeeResult, и я пытаюсь написать простой триггер INSERT для EmployeeResult, который делает это - каждый раз, когда INSERT выполняется в EmployeeResult, например:

(Джек, 200, Продажи) (Джейн, 300, Маркетинг) (Джон, 400, Инженерное дело)

Он должен искать пары записей "Имя" и "Отдел", например

(Джек, отдел продаж), (Джейн, маркетинг), (Джон, инжиниринг)

в таблице «Сотрудник», и если такой сотрудник не существует, следует вставить его в таблицу «Сотрудник».

То, что у меня есть, это то, что неизвестно, как исправить "???":

CREATE TRIGGER trig_Update_Employee
ON [EmployeeResult]
FOR INSERT
AS
IF EXISTS (SELECT COUNT(*) FROM Employee WHERE ???)
  BEGIN
   INSERT INTO [Employee] (Name, Department) VALUES (???, ???)
  END

Пожалуйста, помогите, заранее спасибо

Схема:

Employee
--------
Name, varchar(50)
Department, varchar (50)

EmployeeResult
--------------
Name, varchar(50)
Salary, int
Department, varchar (50)

person Anonymous Coward    schedule 31.08.2009    source источник


Ответы (3)


Вы хотите воспользоваться преимуществами вставленной логической таблицы, доступной в контексте триггера. Он соответствует схеме для таблицы, в которую вставляется, и включает строки, которые будут вставлены (в триггере обновления у вас есть доступ к вставленным и удаленным логические таблицы, которые представляют новые и исходные данные соответственно.)

Итак, чтобы вставить пары Сотрудник / Отдел, которые в настоящее время не существуют, вы можете попробовать что-то вроде следующего.

CREATE TRIGGER trig_Update_Employee
ON [EmployeeResult]
FOR INSERT
AS
Begin
    Insert into Employee (Name, Department) 
    Select Distinct i.Name, i.Department 
    from Inserted i
    Left Join Employee e
    on i.Name = e.Name and i.Department = e.Department
    where e.Name is null
End
person cmsjr    schedule 31.08.2009

У cmsjr было правильное решение. Я просто хотел указать на пару моментов для вашего будущего развития триггера. Если вы используете оператор values ​​во вставке в триггер, существует большая вероятность того, что вы делаете что-то не так. Триггеры срабатывают один раз для каждого пакета вставленных, удаленных или обновленных записей. Таким образом, если десять записей были вставлены в один пакет, то триггер срабатывает один раз. Если вы ссылаетесь на данные во вставленных или удаленных и используете переменные и предложение значений, вы получите данные только для одной из этих записей. Это вызывает проблемы с целостностью данных. Вы можете исправить это, используя вставку на основе набора, как показано в cmsjr выше, или с помощью курсора. Никогда не выбирайте путь курсора. Курсор в триггере - это проблема, ожидающая своего появления, поскольку они медленные и могут заблокировать вашу таблицу на несколько часов. Я удалил курсор с триггера один раз и улучшил процесс импорта с 40 минут до 45 секунд.

Вы можете подумать, что никто никогда не будет добавлять несколько записей, но это происходит чаще, чем думает большинство людей, не связанных с базами данных. Не пишите триггер, который не будет работать при всех возможных условиях вставки, обновления и удаления. Никто не будет использовать метод одной записи за раз, когда ему нужно импортировать 1000000 записей о продажах от нового клиента или обновить все цены на 10% или удалить все записи у поставщика, продукты которого вы больше не продаете.

person HLGEM    schedule 31.08.2009

проверьте этот код:

CREATE TRIGGER trig_Update_Employee ON [EmployeeResult] FOR INSERT AS Begin   
    Insert into Employee (Name, Department)  
    Select Distinct i.Name, i.Department   
        from Inserted i
        Left Join Employee e on i.Name = e.Name and i.Department = e.Department
        where e.Name is null
End
person deepak    schedule 30.05.2011