Skip to main content

通过实例,用SQLite代替触发器

SQLite中的替代触发器是什么

在SQLite中,只能基于视图而不是表创建替代触发器。

视图在SQLite中是只读的。如果您针对视图发出一条DML语句,如INSERT、UPDATE或DELETE,您将收到一个错误。

当视图具有INSTEAD OF触发器时,当您发出相应的DML语句时,触发器将触发。这允许您在处理流中注入自己的逻辑。

例如,如果一个视图有一个INSERT而非INSERT触发器,当您发出INSERT语句时,该触发器将自动触发。在触发器内部,可以执行插入、更新或删除基表中的数据。

换句话说,INSTEAD OF触发器允许视图变得可修改。

以下说明了在SQLite中创建替代触发器的语法:

CREATE TRIGGER [IF NOT EXISTS] schema_ame.trigger_name
INSTEAD OF [DELETE | INSERT | UPDATE OF column_name]
ON table_name
BEGIN
-- insert code here
END;

在这种语法中:

SQLite而不是触发器示例

对于演示,我们将使用示例数据库中的艺术家和专辑表。

首先,根据艺术家和相册表中的数据创建名为AlbumArtisters的视图:

CREATE VIEW AlbumArtists(
AlbumTitle,
ArtistName
) AS
SELECT
Title,
Name
FROM
Albums
INNER JOIN Artists USING (ArtistId);

其次,使用此查询验证视图中的数据:

SELECT * FROM AlbumArtists;

第三,在AlbumArtisters视图中插入新行:

INSERT INTO AlbumArtists(AlbumTitle,ArtistName)
VALUES('Who Do You Trust?','Papa Roach');

SQLite发出了以下错误:

[SQLITE_ERROR] SQL error or missing database (cannot modify AlbumArtists because it is a view)    

第四,创建一个INSTEAD OF触发器,在将新行插入AlbumArtisters表时触发:

CREATE TRIGGER insert_artist_album_trg
INSTEAD OF INSERT ON AlbumArtists
BEGIN
-- insert the new artist first
INSERT INTO Artists(Name)
VALUES(NEW.ArtistName);

-- use the artist id to insert a new album
INSERT INTO Albums(Title, ArtistId)
VALUES(NEW.AlbumTitle, last_insert_rowid());
END;

在此触发器中:

最后,验证艺术家和专辑表中的插入:

SELECT
*
FROM
Artists
ORDER BY
ArtistId DESC;

SELECT
*
FROM
Albums
ORDER BY
AlbumId DESC;

SQLite INSTEAD OF Trigger - Artists Table

正如您看到的输出,艺术家和专辑表中插入了一个新行。

在本教程中,您了解了SQLite替代触发器,以及如何创建替代插入触发器,以便通过视图将数据插入基表。