Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 触发器在不应该触发的情况下引发消息_Php_Sql_Sqlite_Pdo_Triggers - Fatal编程技术网

Php 触发器在不应该触发的情况下引发消息

Php 触发器在不应该触发的情况下引发消息,php,sql,sqlite,pdo,triggers,Php,Sql,Sqlite,Pdo,Triggers,我在一个表上附加了一个触发器,当某些列的组合不是唯一的时,它应该引发异常 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 = N

我在一个表上附加了一个触发器,当某些列的组合不是唯一的时,它应该引发异常

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;
显然,当排序规则thingy处于活动状态时,foo5名称等于foo5

如果删除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")');

您可以发布表def和一些意外抛出的示例数据吗?您是否尝试显式命名列,如a.safe_name=NEW.safe_name?我的猜测是,SELECT中除safe_name之外的条件是匹配的。我添加了更多详细信息。我不能这样做,因为我需要对排序结果进行不区分大小写的比较。但我不知道为什么sqlite在选择x=y时使用它。这没有意义…COLLATE BINARY是默认的排序规则吗?谢谢!我从create table中删除了COLLATE语句,并将COLLATE NS添加到要使用自然排序的查询中的ORDER BY语句中。似乎有效
$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")');