我想创建一个触发器,以防止值输入超过某个值。
我已经阅读了一点,但无法将下面的问题与我自己的问题联系起来。
Trigger to fire only if a condition is met in SQL Server
代码:
ALTER TRIGGER Tgr_IQRating
ON dbo.Customer
FOR UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @IQ int
Select @IQ = IQRATING from dbo.customer
IF (@IQ) > 150
BEGIN
PRINT ('Cannot enter anything higher than 100')
END
ROLLBACK TRANSACTION
END
我试过这样的
IF (IQRating) > 150
BEGIN
PRINT ('Cannot enter anything higher than 100')
END
ROLLBACK TRANSACTION
但是得到一个无法找到列的错误。此外,当我尝试更新时,以下内容失败。
IF (SELECT IQRating FROM dbo.customer) > 150
BEGIN
PRINT ('Cannot enter anything higher than 100')
END
错误:
消息512,级别16,状态1,过程Tgr_IQRating,第16行
子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。
任何帮助都会很棒。
谢谢,
杰
答案 0 :(得分:1)
你真的应该为此使用约束。它更适合SQL。
答案 1 :(得分:0)
您应该使用特殊的“表”inserted
来查看正在更新的数据,否则您正在查看包含其他行的整个表。
IF EXISTS(SELECT 1 FROM inserted WHERE IQRating > 150)
BEGIN
PRINT ('Cannot enter anything higher than 150')
END
更好的解决方案是使用RAISERROR
或SQL Server 2012 THROW
语句而不是PRINT
,以便将错误消息发送回发起更新的任何人。
答案 2 :(得分:0)
你有多个问题。首先,您将回滚100%的时间,因为回滚不在IF块中。
下一步
Select @IQ = IQRATING from dbo.customer
是您的子查询问题。我假设客户有多个记录!而你无论如何都应该引用插入的伪节点。
第三,你似乎认为触发器一次只能在一行上运行。它将分批运作。这样做的一个线索是你正在填充一个标量变量。假设在更新中只有一条记录是不负责任和不专业的。
你还需要对INSERT进行检查吗?或者这些数据是否仅在更新中填充?
目前还不清楚是否希望整个事务在一条记录错误时回滚,或者如果要查找插入的任何错误记录并仅保留这些数据库。每种可能性的代码都是不同的。
编辑其中一些是针对SQL服务器的(我没有看到mysql标签,但你在文本中引用了SQL服务器,所以我做了一个假设。)代码看起来像T_SQL代码。