繁体   English   中英

触发器在不应该引发消息时引发消息

[英]Trigger raises message when it's not supposed to

我有一个附加到表的触发器,当某些列的组合不唯一时,该表应该引发异常。

CREATE TRIGGER uniqueness BEFORE INSERT ON a
  BEGIN
    SELECT RAISE(FAIL, 'Record is not unique !')
    FROM a
    WHERE ((NEW.st <> 1) 
      AND (p = NEW.p)
      AND ((name = NEW.name) OR (safe_name = NEW.safe_name)));
  END;

但似乎有时会在没有必要时触发。

例如,如果safe_name是foo5 ,并且存在具有safe_name foo-5的现有记录。 但是foo5 != foo-5那么为什么会这样呢?

================================================== ===========

好吧,我发现了它为什么会发生。 这是你如何在PHP中重现它:

$pdo = new PDO('sqlite::memory:');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);      
$pdo->sqliteCreateCollation('NS', 'strnatcasecmp');      

$pdo->query('CREATE TABLE a(
   id INTEGER PRIMARY KEY AUTOINCREMENT,
   st INTEGER NOT NULL,
   p  INTEGER NOT NULL,
   name TEXT NOT NULL COLLATE NS,
   safe_name NOT NULL COLLATE NS)');

$pdo->query('CREATE TRIGGER uniqueness BEFORE INSERT ON a
  BEGIN
    SELECT RAISE(FAIL, "Record is not unique !")
    FROM a
    WHERE ((NEW.st <> 1) 
      AND (p = NEW.p)
      AND ((name = NEW.name) OR (safe_name = NEW.safe_name)));
  END;');

// success
$pdo->query('INSERT INTO a(st, p, name, safe_name) VALUES(2, 2, "Foo 5", "foo-5")');

// fail :(
$pdo->query('INSERT INTO a(st, p, name, safe_name) VALUES(2, 2, "foo  5", "foo5")');

当collat​​ion thingy处于活动状态时,显然Foo 5名称等于foo 5

如果我删除sqliteCreateCollation调用和COLLATE NS语句它工作:/

是否有任何解决方案可以让我保持整理功能? 我只需要订购,但显然它也用于比较......

您已经专门设置了排序规则以进行不区分大小写的比较。 尝试将其更改为:

$pdo->sqliteCreateCollation('NS', 'strnatcmp');

看看是否有帮助。

您应该能够将排序规则保留在原位,但仅将其切换为二进制以进行触发器查询。

$pdo = new PDO('sqlite::memory:');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);      
$pdo->sqliteCreateCollation('NS', 'strnatcasecmp');      

$pdo->query('CREATE TABLE a(
   id INTEGER PRIMARY KEY AUTOINCREMENT,
   st INTEGER NOT NULL,
   p  INTEGER NOT NULL,
   name TEXT NOT NULL COLLATE NS,
   safe_name NOT NULL COLLATE NS)');

$pdo->query('CREATE TRIGGER uniqueness BEFORE INSERT ON a
  BEGIN
    SELECT RAISE(FAIL, "Record is not unique !")
    FROM a
    WHERE ((NEW.st <> 1) 
      AND (p = NEW.p)
      AND ((name COLLATE BINARY = NEW.name) OR (safe_name COLLATE BINARY = NEW.safe_name)));
  END;');

// success
$pdo->query('INSERT INTO a(st, p, name, safe_name) VALUES(2, 2, "Foo 5", "foo-5")');

// should work now
$pdo->query('INSERT INTO a(st, p, name, safe_name) VALUES(2, 2, "foo  5", "foo5")');

暂无
暂无

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

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