插入触发器前的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
的列。