繁体   English   中英

sql触发器-if语句-阻止更新

[英]sql trigger - if statement - Prevent update

我想创建一个触发器,以防止输入的值超过某个特定值。

我读了一点,但是不能将以下问题与我自己的问题联系起来。

仅在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。 当子查询遵循=,!=,<,<=,>,> =或将子查询用作表达式时,不允许这样做。

任何帮助都会很棒。

谢谢,

周杰伦

您确实应该为此使用约束。 对于SQL来说更习惯。

检查约束

您应该使用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以便将错误消息发送回发起更新的任何人。

您有多个问题。 首先,由于回滚不在IF块中,因此您将回滚100%的时间。

下一个

Select @IQ = IQRATING from dbo.customer

是您的子查询问题。 我假设客户有多个记录! 无论如何,您可能应该引用插入的伪表。

第三,您似乎认为触发器一次只能在一行上运行。 它将分批运行。 这可能是因为您正在填充标量变量。 假设在更新中只有一条记录是不负责任和不专业的。

您还需要在INSERT上执行此检查吗? 还是仅在更新中填充此数据?

目前尚不清楚是否要回退整个事务,如果一条记录是不良记录,还是要查找插入的不良记录并仅保留那些数据库。 每个可能性的代码将不同。

编辑其中一些用于SQL Server(我没有看到mysql标记,但是您在文本中引用了SQL Server,所以我作了一个假设。)尽管如此,代码看起来像T_SQL代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM