我有一个附加到表的触发器,当某些列的组合不唯一时,该表应该引发异常。
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语句:/
是否有任何解决方案可以让我保持校对功能?我只需要订购,但显然它也用于比较......
答案 0 :(得分:1)
您已经专门设置了排序规则以进行不区分大小写的比较。尝试将其更改为:
$pdo->sqliteCreateCollation('NS', 'strnatcmp');
看看是否有帮助。
答案 1 :(得分:1)
您应该可以将排序规则保留在原位,但只能将其切换为二进制文件以进行触发器查询。
$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")');