Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.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
插入触发器前的SQLite_Sql_Sqlite_Sqlitestudio - Fatal编程技术网

插入触发器前的SQLite

插入触发器前的SQLite,sql,sqlite,sqlitestudio,Sql,Sqlite,Sqlitestudio,当违反PKA时,我尝试在插入触发器之前使用将重复数据插入表B,如下示例: CREATE TABLE A( Col INTEGER, Coll TEXT(25), CONSTRAINT PKA PRIMARY KEY(Col, Coll) ON CONFLICT IGNORE); CREATE UNIQUE INDEX IX_A ON A(Col, Coll); CREATE TABLE B( Col INTEGER, Coll TEXT(25)); CREATE INDEX IX_B ON B

当违反
PKA
时,我尝试在插入触发器之前使用
将重复数据插入表
B
,如下示例:

CREATE TABLE A( Col INTEGER, Coll TEXT(25), CONSTRAINT PKA PRIMARY KEY(Col, Coll) ON CONFLICT IGNORE);
CREATE UNIQUE INDEX IX_A ON A(Col, Coll);

CREATE TABLE B( Col INTEGER, Coll TEXT(25));
CREATE INDEX IX_B ON B(Col, Coll);

CREATE TRIGGER Trig
BEFORE INSERT
ON A
WHEN (Col = New.Col AND Coll = New.Coll)
BEGIN
      INSERT INTO B(Col, Coll) VALUES(New.Col, New.Coll);
END;
但是,这里似乎无法访问列
Col
,因此它抛出:

没有这样的专栏:Col

即使我把条件改成

New.Col IN(SELECT Col FROM A)
AND
New.Coll IN(SELECT Coll FROM A)
我收到另一条错误消息:

唯一约束失败:A.列,A.列

虽然它不应该因为冲突而忽略

  • 为什么我会收到这些错误消息?(原因是什么)
  • 如何使用触发器将重复项插入到另一个表中

    • 您不需要索引:

      CREATE UNIQUE INDEX IX_A ON A(Col, Coll);
      
      因为您已经将
      (Col,Coll)
      定义为
      主键
      ,而且使用此索引,尽管您已经为重复行定义了
      ON CONFLICT IGNORE
      ,但是如果您尝试插入重复行,您将收到一个错误,因为没有为索引定义
      ON CONFLICT IGNORE

      所以放下它:

      DROP INDEX IF EXISTS IX_A;
      
      现在,将触发器的代码更改为:

      CREATE TRIGGER Trig
      BEFORE INSERT
      ON A
      WHEN EXISTS (SELECT 1 FROM A WHERE Col = New.Col AND Coll = New.Coll)
      BEGIN
            INSERT INTO B(Col, Coll) VALUES(New.Col, New.Coll);
      END;
      
      存在
      检查表
      A
      是否已包含列值与要插入列值相同的行,如果已存在,则将新行插入表
      B

      您也可以这样编写触发器:

      CREATE TRIGGER Trig
      BEFORE INSERT
      ON A
      BEGIN
            INSERT INTO B(Col, Coll)
            SELECT Col, Coll FROM A
            WHERE (Col, Coll) = (New.Col, New.Coll);
      END;
      

      谢谢你的回答。您的
      唯一索引是正确的,我没有注意到它。但是,请您进一步解释一下为什么当(Col=New.Col和Coll=New.Coll)
      EXISTS()
      有效时,前提条件
      不起作用?@Ilyes在插入/更新触发器中,您可以使用关键字New引用新行的列值。因此,NEW.Col和NEW.Coll的定义是正确的。但是
      Col
      Coll
      在任何地方都没有定义。他们需要成为从…中选择的一部分。。。要识别为表列的语句。它们在为特定表定义的触发器中使用的事实并不将它们定义为该表的列。另一方面,在类似这样的语句中:
      从列中选择1,其中Col=New.Col和Coll=New.Coll
      它们被正确定义为
      a
      的列。