не могу создать триггер - SQL Server 2008 - PullRequest
1 голос
/ 02 июня 2011

Я пытаюсь сделать следующее:

CREATE TRIGGER checkgrade ON 
[Homework4part3].[dbo].[Enrollment]
FOR INSERT
AS
    IF (NEW.grade > 20)
    BEGIN
    grade = 3
    END

GO

и моя таблица выглядит следующим образом:

Зачисление (курс №, QYear, SUID, единицы, класс)

Не знаю, почему отображается эта ошибка:

Msg 102, Level 15, State 1, Procedure checkgrade, Line 7
Incorrect syntax near 'grade'.

Ответы [ 5 ]

3 голосов
/ 02 июня 2011

Я попытаюсь немного прочитать между строк. Очевидно, я сделал лучшее предположение об условии соединения. Я думаю, что это то, чего вы пытаетесь достичь.

CREATE TRIGGER checkgrade ON 
[Homework4part3].[dbo].[Enrollment]
FOR INSERT
AS
    UPDATE e
        SET grade = 3
        FROM inserted i
            INNER JOIN enrollment e
                ON i.coursenum = e.coursenum
                    AND i.QYear = e.QYear
                    AND I.SUID = e.SUID
        WHERE i.grade > 20

GO
2 голосов
/ 02 июня 2011

Я предлагаю вам использовать триггер вместо, чтобы уменьшить количество записей в таблицу.Использование обновления в триггере приведет к удалению, а затем к вставке, так что всего три операции выполняются на столе.Использование вместо триггера повлечет за собой только одну операцию

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[BaseTable]') AND type in (N'U'))
DROP TABLE [dbo].[BaseTable]
GO

CREATE TABLE BaseTable
  (BaseTableID     int PRIMARY KEY IDENTITY(1,1),
   course@ int,
   QYear int,
   SUID int,
   units int,
   Grade int
  )
GO


--Create an INSTEAD OF INSERT trigger on the table.
CREATE TRIGGER InsteadTrigger on BaseTable
INSTEAD OF INSERT
AS
BEGIN

  INSERT INTO BaseTable
       SELECT 
          course@ ,
           QYear ,
           SUID ,
           units ,
           CASE  
           WHEN Grade > 20 THEN 3
           ELSE Grade
           END
       FROM inserted
END
GO

INSERT INTO [deleteme].[dbo].[BaseTable]
           ([course@]
           ,[QYear]
           ,[SUID]
           ,[units]
           ,[Grade])
     VALUES
           (10
           ,10
           ,10
           ,10
           ,10)
Select * from BaseTable

INSERT INTO [deleteme].[dbo].[BaseTable]
           ([course@]
           ,[QYear]
           ,[SUID]
           ,[units]
           ,[Grade])
     VALUES
           (20
           ,20
           ,20
           ,20
           ,20)

Select * from BaseTable
INSERT INTO [deleteme].[dbo].[BaseTable]
           ([course@]
           ,[QYear]
           ,[SUID]
           ,[units]
           ,[Grade])
     VALUES
           (30
           ,30
           ,30
           ,30
           ,30),
           (40
           ,40
           ,40
           ,40
           ,40),
           (50
           ,50
           ,50
           ,50
           ,50)



Select * from BaseTable


BaseTableID course@ QYear   SUID    units   Grade
1   10  10  10  10  10
2   20  20  20  20  20
3   30  30  30  30  3
4   40  40  40  40  3
5   50  50  50  50  3
1 голос
/ 03 июня 2011

Сообщение 102, Уровень 15, Состояние 1, Процедура checkgrade, строка 7 Неверный синтаксис около "класса".

Это означает, что использованный вами синтаксис был недопустимым. Вот почему некоторые другие дали вам другой синтаксис, чтобы попробовать.

Сообщение 2108, Уровень 15, Состояние 1, Процедура checkgrade, строка 7 не может создать активировать "Homework4part3.dbo.Enrollment" в качестве цель отсутствует в текущей базе данных

Это означает, что вы пытаетесь создать триггер на несуществующей таблице. Или это означает, что сказано в этой ссылке: http://social.msdn.microsoft.com/Forums/en/transactsql/thread/64637d9e-8080-411e-a9c6-e228c6437f30

Теперь давайте поговорим о некоторых основах триггера. Прежде всего, вам нужно спроектировать все триггеры в SQL Server для обработки вставки, обновления или удаления нескольких строк. Это означает, что вы должны предположить, что в действии было изменено более одной записи.

Следующие триггеры имеют две псевдотаблицы, называемые вставленными и удаленными, которые показывают значения до действий (удаленная таблица) и значение после действия (вставленная таблица). Обновления содержат информацию в обеих таблицах, в то время как вставки содержат информацию только во вставленных, а удаления - только в удаленных. Эти таблицы используются для поиска записей, с которыми вы хотите что-то сделать. У @Joe Stefanelli есть хороший пример того, как использовать вставленную таблицу.

Следующее, что вы хотите понять о триггерах, это то, что они добавляют время к любым действиям на столе, и поэтому они должны быть максимально быстрыми. Таким образом, никакие коррелированные подзапросы, курсоры или циклы не должны использоваться.

1 голос
/ 02 июня 2011

Есть несколько проблем.

Вам необходимо использовать вставленную мета-таблицу, которая охватывает недавно обновленные / вставленные строки.Необходимо выполнить правильное обновление, поскольку триггер выполняется после обновления / вставки, а не в середине.

Это может быть ближе к тому, что требуется:

 CREATE TRIGGER checkgrade ON 
    [Homework4part3].[dbo].[Enrollment]
    FOR INSERT
    AS
    BEGIN
        SET NOCOUNT ON

        Update e
        set grade = 3
        from 
            [Homework4part3].[dbo].[Enrollment] e
            join Inserted i on e.SUID = i.SUID and e.[course#] = i.[course#]
        where i.grade > 20

    END

Примечание: этоне проверен, и я догадался о столбцах первичного ключа в вашей таблице.

0 голосов
/ 02 июня 2011
IF (SELECT GRADE FROM INSERTED) > 20
BEGIN
   UPDATE Enrollment
   SET GRADE = 3
   WHERE course = (SELECT COURSE FROM INSERTED), 
   AND QYear = (SELECT QYear FROM INSERTED),
   AND SUID = (SELECT SUID FROM INSERTED),
   AND units = (SELECT UNITS FROM INSERTED)
END

Если я хорошо помню, вы не можете использовать более одной таблицы в операторе обновления, поэтому ответ @Joe Stefanelli будет работать не так, как ожидалось, но идея верна.

Надеюсь, что это работает.

...