我认为对于那些使用T-SQL,尤其是触发器工作很多的人来说,这将是一个简单的问题:
我希望对此表的所有更新和插入强制执行以下约束:
如果在插入或更新表中这两个条件中的任何一个失败,我想返回一个适当的错误。
触发器似乎还没有做任何事情。 。您可以提供必要的更改,使其按照描述执行吗?
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
我得到了它的工作。我没有读过触发器来弥补我基本上缺乏理解,但他似乎工作,虽然我相信Check Constraint是更好的方法:
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.
答案 0 :(得分:5)
我使用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&lt;&gt; 1,Flatfee必须为NULL”等等
答案 1 :(得分:1)
你从根本上不理解触发器。您需要做的第一件事是阅读有关联机丛书中的触发器,特别强调了解插入和删除的psuedotables。接下来你需要知道的是触发器应该永远不会被写入,就好像它一次只能处理一条记录一样。触发器对批量记录进行操作,触发器代码必须考虑到这一点。
答案 2 :(得分:0)
我不相信触发器会引发错误,问题#1。