插入触发器之前的SQLite

问题描述

当尝试使用B违反PKA时,我试图将重复数据插入表BEFORE INSERT TRIGGER中,如下例所示:

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.Col,A.Coll

不是因为ON CONFLICT IGnorE而引起的。

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

解决方法

您不需要索引:

CREATE UNIQUE INDEX IX_A ON A(Col,Coll);

因为您已经将(Col,Coll)定义为PRIMARY KEY,并且使用此索引,尽管您为重复的行定义了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;

EXISTS检查表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;

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...