一直在尝试编写这个触发器,但我真的做不出来..
我需要做的:
从项目表中删除一个项目,但同时删除与该项目相关的任何问题以及与该问题相关的任何问题更新。然后需要将这些删除的记录与删除时间以及删除它们的运算符(operator)的 ID 一起存储在归档表中。
一个问题可能有几个与之相关的更新,因为一个项目可能有许多与之相关的问题。
我已将所有模式放在 SQL fiddle 中,因为它在那里更容易处理,但如果需要,我会把它放在这里。
SQL fiddle 的链接:
http://sqlfiddle.com/#!1/1bb25
编辑:我想我不妨把它放在这里..
Tables:
CREATE TABLE Operator
(
ID INTEGER NOT NULL PRIMARY KEY,
Name VARCHAR(40) NOT NULL
);
CREATE TABLE Item
(
ID INTEGER NOT NULL PRIMARY KEY,
Name VARCHAR(40) NOT NULL
);
CREATE TABLE Faq
(
ID INTEGER NOT NULL PRIMARY KEY,
Question VARCHAR(150) NOT NULL,
Answer VARCHAR(2500) NOT NULL,
ItemID INTEGER,
FOREIGN KEY (ItemID) REFERENCES Item(ID)
);
CREATE TABLE Customer
(
ID INTEGER NOT NULL PRIMARY KEY,
Name VARCHAR(20) NOT NULL,
Email VARCHAR(20) NOT NULL
);
CREATE TABLE Question
(
ID INTEGER NOT NULL PRIMARY KEY,
Problem VARCHAR(1000),
AskedTime TIMESTAMP NOT NULL,
CustomerID INTEGER NOT NULL,
ItemID INTEGER NOT NULL,
FOREIGN KEY (ItemID) REFERENCES Item(ID),
FOREIGN KEY (CustomerID) REFERENCES Customer(ID)
);
CREATE TABLE qUpdate
(
ID INTEGER NOT NULL PRIMARY KEY,
Message VARCHAR(1000) NOT NULL,
UpdateTime TIMESTAMP NOT NULL,
QuestionID INTEGER NOT NULL,
OperatorID INTEGER,
FOREIGN KEY (OperatorID) REFERENCES Operator(ID),
FOREIGN KEY (QuestionID) REFERENCES Question(ID)
);
-- Archive Tables
CREATE TABLE DeletedQuestion
(
ID INTEGER NOT NULL PRIMARY KEY,
Problem VARCHAR(1000),
AskedTime TIMESTAMP NOT NULL,
CustomerID INTEGER NOT NULL,
ItemID INTEGER NOT NULL
);
CREATE TABLE DeletedqUpdate
(
ID INTEGER NOT NULL PRIMARY KEY,
Message VARCHAR(1000) NOT NULL,
UpdateTime TIMESTAMP NOT NULL,
Question INTEGER NOT NULL
);
CREATE TABLE DeletedItem
(
ID INTEGER NOT NULL PRIMARY KEY,
Name VARCHAR(40) NOT NULL,
OperatorDeleteID INTEGER NOT NULL,
FOREIGN KEY (OperatorDeleteID) REFERENCES Operator(ID)
);
一些用于测试的样本插入
--Product Inserts
INSERT INTO Item (ID, Name) VALUES (1, 'testitem1');
INSERT INTO Item (ID, Name) VALUES (2, 'testitem2');
--Operator Inserts
INSERT INTO Operator (ID, Name) VALUES (1, 'testname1');
INSERT INTO Operator (ID, Name) VALUES (2, 'testname2');
--Faq Inserts
INSERT INTO Faq (ID, Question, Answer, ItemID) VALUES (1, 'testq1', 'testa1', 1);
INSERT INTO Faq (ID, Question, Answer, ItemID) VALUES (2, 'testq2', 'testa2', 2);
-- Customer Inserts
INSERT INTO Customer (ID, Name, Email) VALUES (1, 'testcust1', 'testemail1');
INSERT INTO Customer (ID, Name, Email) VALUES (2, 'testcust2', 'testemail2');
-- Question Inserts
INSERT INTO Question (ID, Problem, AskedTime, CustomerID, ItemID) VALUES (1,'testproblem1','2012-03-14 09:30',1,1);
INSERT INTO Question (ID, Problem, AskedTime, CustomerID, ItemID) VALUES (2,'testproblem1','2012-07-14 09:30',2,1);
INSERT INTO qUpdate (ID, Message, UpdateTime, OperatorID, QuestionID) VALUES (1, 'test1','2012-05-14 09:30', 1, 1);
INSERT INTO qUpdate (ID, Message, UpdateTime, OperatorID, QuestionID) VALUES (2, 'test2','2012-08-14 09:30', 2, 1);
最佳答案
首先要做的是了解在 PostgreSQL 中,CREATE TRIGGER
语句将触发器函数 绑定(bind)到表上的一个或多个操作,所以让我们从函数的语法。您可以使用各种脚本语言编写触发器函数,但最常见的是 plpgsql。一个简单的函数可能如下所示:
CREATE OR REPLACE FUNCTION Question_delete_trig_func()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
INSERT INTO DeletedQuestion
SELECT OLD.*;
RETURN OLD;
END;
$$;
删除后运行:
CREATE TRIGGER Question_delete_trig
AFTER DELETE ON Question
FOR EACH ROW EXECUTE PROCEDURE Question_delete_trig_func();
这应该足以让您入门。
对于应从中保存已删除行的每个表,您应该有一个这样的触发器。然后您需要确定如何进行删除。您可以将适当的外键定义为 ON DELETE CASCADE
并让 PostgreSQL 为您完成。
关于sql - 需要帮助编写 SQL 触发器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10096861/