Простой вопрос триггера - PullRequest
       9

Простой вопрос триггера

2 голосов
/ 04 ноября 2010

Я думаю, что это будет простой вопрос для тех, кто много работает с T-SQL и особенно с триггерами:

Я хочу применить следующие ограничения для всех обновлений и вставок в эту таблицу:

  1. Если DiscountTypeId = 1, то FlatFee не должен быть равен NULL.
  2. Если DiscountTypeId = 2, то DiscountRate не должно быть нулевым.

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

Триггер, похоже, еще ничего не делает. Можете ли вы предоставить необходимые изменения, чтобы они работали, как описано?

USE [PandaVisa2008]
GO

/****** Object:  Table [dbo].[CustomerSpeed]    Script Date: 11/04/2010 15:51:10 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[CustomerSpeed](
 [CustomerSpeedId] [int] NOT NULL,
 [CustomerId] [int] NULL,
 [SpeedId] [int] NOT NULL,
 [DiscountTypeId] [int] NOT NULL,
 [FlatFee] [money] NULL,
 [DiscountRate] [decimal](3, 3) NULL,
 CONSTRAINT [PK_AgentFee] PRIMARY KEY CLUSTERED 
(USE [PandaVisa2008]

GO

/****** Object:  Trigger [dbo].[TRG_CustomerSpeed_OnInsertUpdate]    Script Date: 11/04/2010 15:38:06 ******/
SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

ALTER TRIGGER [dbo].[TRG_CustomerSpeed_OnInsertUpdate]
ON [dbo].[CustomerSpeed]
FOR INSERT, UPDATE
AS
    BEGIN

        DECLARE @DiscountTypeId INT
        DECLARE @FlatFee MONEY
        DECLARE @DiscountRate DECIMAL(3, 3)

        SELECT
            @DiscountTypeId = DiscountTypeId,
            @FlatFee = FlatFee,
            @DiscountRate = DiscountRate
        FROM
            inserted

        IF @DiscountTypeId = 1
           AND @FlatFee IS NULL
            BEGIN
                RAISERROR (N'If @DiscountTypeId is 1, FlatFee must not be NULL',
                           10,
                           1)
            END

  IF @DiscountTypeId = 2
           AND @DiscountRate IS NULL
            BEGIN
                RAISERROR (N'If @DiscountTypeId is 2, @DiscountRate must not be NULL',
                           10,
                           1)
            END            
    END 

 [CustomerSpeedId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[CustomerSpeed]  WITH CHECK ADD  CONSTRAINT [CK_CustomerSpeed] CHECK  (([DiscountRate]>(0) AND [DiscountRate]<(1)))
GO

ALTER TABLE [dbo].[CustomerSpeed] CHECK CONSTRAINT [CK_CustomerSpeed]
GO

EDIT

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

ALTER TRIGGER [dbo].[TRG_CustomerSpeed_OnInsertUpdate]
ON [dbo].[CustomerSpeed]
FOR INSERT, UPDATE
AS
    BEGIN
        IF EXISTS (SELECT
                       1
                   FROM
                       inserted I
                   WHERE  I.DiscountTypeId = 1
                      AND I.FlatFee IS NULL)
            BEGIN
                ROLLBACK TRANSACTION

                RAISERROR (N'If DiscountTypeId is 1, FlatFee must not be NULL',
                           10,
                           1)
            END

       IF EXISTS (SELECT
                       1
                   FROM
                       inserted I
                   WHERE  I.DiscountTypeId = 2
                      AND I.DiscountRate IS NULL)
            BEGIN
                ROLLBACK TRANSACTION

                RAISERROR (N'If DiscountTypeId is 2, DiscountRate must not be NULL',
                           10,
                           1)
            END            
    /*
     IF @DiscountTypeId = 2
        AND @DiscountRate IS NULL
         BEGIN
         Rollback Transaction
             RAISERROR (N'If @DiscountTypeId is 2, DiscountRate must not be NULL',
                        10,
                        1)
         END
    */
    END 

Your comments are welcomed.

Ответы [ 3 ]

5 голосов
/ 04 ноября 2010

Я бы использовал ограничение CHECK, а не триггеры

ALTER TABLE Mytable WITH CHECK ADD
   CONSTRAINT CK_MyTable_GoodName CHECK (
        NOT (DiscountTypeId = 1 AND Flatfee IS NULL)
        AND
        NOT (DiscountTypeId = 2 AND DiscountRate IS NULL)
)

Кроме того, необходимо учитывать «если DiscountTypeId <> 1, должен ли Flatfee быть НЕДЕЙСТВИТЕЛЕН» и т. Д.

1 голос
/ 04 ноября 2010

Вы принципиально не понимаете триггеров.Самое первое, что вам нужно сделать, это прочитать о триггерах в Books Online с особым акцентом на изучение вставленных и удаленных psuedotables.Следующее, что вам нужно знать, это триггер, который НИКОГДА не должен быть написан так, как если бы он обрабатывал только одну запись за раз.Триггеры работают с пакетами записей, и код триггера должен учитывать это.

0 голосов
/ 04 ноября 2010

Я не верю, что триггеры могут вызвать ошибки, проблема №1.

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