2012-04-10 108 views
1

一直试图写这个触发器,但我真的不能工作了..需要帮助编写SQL触发

我需要做什么:

从项目表中删除的项目,但在同一及时删除与该项目相关的任何问题以及与该问题相关的任何问题更新。这些删除的记录随后需要存储在删除时间的归档表中以及删除它们的操作员的ID中。

一个问题可能有几个更新与它相关联,因为一个项目可能有很多与其相关的问题。

我已经把所有模式放在SQL小提琴中,因为它在那里工作要容易得多,但如果需要的话,我会把它放在这里。

链接到SQL小提琴:

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); 
+0

这似乎是plpgsql触发器的非常简单的材料。你有没有试过写一个?在你这样做之前你需要一些特定的信息吗? – kgrittn 2012-04-10 21:55:11

+0

老实说,我是一个在SQL中触发器的完全新手,所以我一般都遇到了麻烦..我读过无数的指南,并且我发现基本语法很难,并且将几个表中的不同值插入到几个表中所有表都在一个触发器中。 以下是我为项目所做的工作:http://sqlfiddle.com/#!1/1bb25/3 – Jimmy 2012-04-10 22:13:06

回答

1

首先要做的是明白在PostgreSQL中,CREATE TRIGGER语句将触发器函数绑定到表上的一个或多个操作,因此让我们从函数的语法开始。您可以用各种脚本语言编写触发器函数,但最常见的是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为您做。

+0

非常感谢您的帮助。那么我不需要为每个桌子都做一个触发器吗? – Jimmy 2012-04-10 22:52:44

+0

这不是解决问题的唯一方法,但我认为这将是构建问题的最佳方式。另外请注意,我使用了最可能的代码作为示例;但是您可能希望列出列,而不是按照INSERT及其SELECT的已定义列顺序列出列。 – kgrittn 2012-04-10 23:14:51