我创建的触发器将太多行插入到审计表中

时间:2014-06-27 22:01:54

标签: sql sqlite triggers

我想在表格中创建历史记录" SampleTableAudit"对于所有插入,更新和删除发生在表" SampleTable"

上的记录的事务

如果我不需要为" SampleTable"上的每个插入记录添加UniqueIdentifier的触发器,这将正常工作。

触发器所做的更新,它在使用新的UniqueIdentifier" SampleTableUID"插入到SampleTable中后更新每个新记录。不应该将触发器的每个执行步骤存储到" SampleTableAudit"只是最终的新纪录,包括UniqieIdentifier。目前,所有3个步骤都在触发插入机制。

CREATE TABLE "SampleTable" (
"SampleTableID" integer PRIMARY KEY AUTOINCREMENT  NOT NULL,
"SampleTableUID" nvarchar,
"Name" nvarchar(50),
"City" nvarchar,
"DateCreated" datetime DEFAULT CURRENT_TIMESTAMP,
"DateModified" datetime,
"UserNameID" integer
);

CREATE TABLE "SampleTableAudit" (
"SampleTableAuditID" integer PRIMARY KEY AUTOINCREMENT  NOT NULL,
"SampleTableID" integer,
"SampleTableUID" nvarchar,
"Name" nvarchar(50),
"City" nvarchar,
"DateCreated" datetime,
"DateModified" datetime,
"UserNameID" integer
);

CREATE TABLE "UserName" (
"UserNameID" integer PRIMARY KEY AUTOINCREMENT  NOT NULL,
"SampleTableUID" nvarchar,
"UserName" nvarchar,
"FullName" nvarchar
);

CREATE TRIGGER "UID"
AFTER INSERT ON "SampleTable"
FOR EACH ROW
BEGIN
UPDATE "SampleTable"
SET "SampleTableUID" = (SELECT substr(u,1,8)||'-'||substr(u,9,4)||'-4'||substr(u,13,3)||
  '-'||v||substr(u,17,3)||'-'||substr(u,21,12) from (
    select lower(hex(randomblob(16))) as u, substr('89ab',random() % 4 + 1, 1) as v))
WHERE rowid = last_insert_rowid();
END;

CREATE TRIGGER "modifiedUPDATE"
AFTER UPDATE ON "SampleTable"
FOR EACH ROW
BEGIN
INSERT INTO  SampleTableAudit ("SampleTableID","SampleTableUID","Name","City","ModifiedType","DateModified","UserNameID",)
values  (old.SampleTableID,old.SampleTableUID,old.Name,old.City,"update",CURRENT_TIMESTAMP,old.UserNameID);
END;

CREATE TRIGGER "modifiedINSERT"
AFTER INSERT ON "SampleTable"
FOR EACH ROW
BEGIN
INSERT INTO  SampleTableAudit ("SampleTableID","SampleTableUID","Name","City","ModifiedType","DateModified","UserNameID",)
values  (new.SampleTableID,new.SampleTableUID,new.Name,new.City,"insert",CURRENT_TIMESTAMP,new.UserNameID);
END;

CREATE TRIGGER "modifiedDELETE"
BEFORE DELETE ON "SampleTable"
FOR EACH ROW
BEGIN
INSERT INTO  SampleTableAudit ("SampleTableID","SampleTableUID","Name","City","ModifiedType","DateModified","UserNameID",)
values  (old.SampleTableID,old.SampleTableUID,old.Name,old.City,"delete",CURRENT_TIMESTAMP,old.UserNameID);
END;

INSERT INTO "SampleTable" ("Name", "City") VALUES ("Russel","Dallas");
INSERT INTO "SampleTable" ("Name", "City") VALUES ("Jones","Seattle");
INSERT INTO "SampleTable" ("Name", "City") VALUES ("McIver","San Diego");
INSERT INTO "SampleTable" ("Name", "City") VALUES ("Mendez","Boston");
INSERT INTO "SampleTable" ("Name", "City") VALUES ("Roberts","Miami");
INSERT INTO "SampleTable" ("Name", "City") VALUES ("Yong","New York");

UPDATE "SampleTable" SET City = 'New York' WHERE Name = "Roberts";

DELETE FROM "SampleTable" WHERE SampleTableID = 2;

1 个答案:

答案 0 :(得分:0)

不应为设置唯一ID的UPDATE运行modifiedUPDATE触发器。 要阻止其运行,请添加WHEN clause以检查该案例(WHEN OLD.SampleTableUID IS NOT NULL)。

modifiedINSERT触发器在NEW值中未看到新的唯一ID,因此这是添加历史记录的错误位置。 相反,您希望在设置新ID时添加此历史记录。 因此,在WHEN子句中使用相反的检查添加UPDATE触发器。

注意:在INSERT触发器中使用last_insert_rowid()是危险的;只需使用NEW.rowid