3

触发器如下:

DELIMITER //
CREATE TRIGGER `Conturi_BI` BEFORE INSERT ON `Conturi` FOR EACH ROW BEGIN
SET NEW.CUI_cod = digits(NEW.CUI);
END//
DELIMITER ;

我只是将数字函数应用于用户输入以更快地匹配和重复搜索,但自从我实现它以来,我的一些插入只是挂起。我做了一个类似的更新,它没有同样的问题。

数字函数是由我创建的,触发器和插入在大多数情况下都可以正常工作。

数字功能,根据要求:

BEGIN
  DECLARE i, len SMALLINT DEFAULT 1;
  DECLARE ret CHAR(32) DEFAULT '';
  DECLARE c CHAR(1);
  SET len = CHAR_LENGTH( str );
  REPEAT
    BEGIN
      SET c = MID( str, i, 1 );
      IF c BETWEEN '0' AND '9' THEN 
        SET ret=CONCAT(ret,c);
      END IF;
      SET i = i + 1;
      END;
  UNTIL i > len END REPEAT;
  RETURN ret;
END
4

2 回答 2

2

如果您传递给它,您的digit功能将不起作用。null它将永远循环。试试看

select digits(null)

所以每次NEW.CUI都是空的,那么它会让你的插入挂起。null您可以在函数的开头添加一个检查:

if str is null
then 
   return '';
end if;
于 2012-10-22T16:22:26.083 回答
1

我最好的猜测是,这是从你的“一些”陈述来看,你遇到了lock contention的问题。

如果我理解你的触发器是正确的,在(实际上是在之前)写入表 A 时,你会触发你的过程,这反过来会改变写入所针对的同一个表 A 中的每条记录,专门锁定单个事务中的每一行。

在另一个事务中这样做很可能会导致死锁情况,您的触发器等待升级锁,而另一个事务等待您的完成(如果您愿意的话,简而言之就是死锁)。

这项努力的成功至少取决于数据库驱动程序的实现。锁定一行,然后在触发的事务中再次锁定它 大多数数据库驱动程序假设事务可以扩展,但是,一些数据库无法看到事务来自同一个连接并单独处理它们。

于 2012-10-22T13:06:26.530 回答