我有一个附加到表的触发器,当某些列组合不唯一时,该触发器应该引发异常。
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")');
显然,当整理事物处于活动状态时,Foo 5
名称是相等的。foo 5
如果我删除sqliteCreateCollation
调用和 COLLATE NS 语句,它会起作用:/
有什么解决方案可以让我保留整理功能吗?我只需要它来订购,但显然它也用于比较......