简体   繁体   中英

Need Help Writing SQL Trigger

Been trying to write this trigger but I can't really work it out..

What I need to do:

Delete an item from the item table but at the same time delete any questions which are associated with the item as well as any questionupdates associated with that question. These deleted records then need to be stored in archived tables with a time of deletion as well as the ID of the operator that deleted them.

A question may have several updates associated with it as may an item have many questions relating to it.

I've put all the schema in the SQL fiddle as it's a lot easier to work on in there but I'll put it in here if needed.

The link to the SQL fiddle:

http://sqlfiddle.com/#!1/1bb25

EDIT: Thought I might as well put it here..

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

Some samples inserts for testing

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

The first thing to do is to understand that in PostgreSQL, a CREATE TRIGGER statement binds a trigger function to one or more operations on a table, so let's start with the syntax of the function. You can write trigger functions in various scripting languages, but the most common is plpgsql. A simple function might look like this:

CREATE OR REPLACE FUNCTION Question_delete_trig_func()
  RETURNS TRIGGER
  LANGUAGE plpgsql
AS $$
BEGIN
  INSERT INTO DeletedQuestion
    SELECT OLD.*;
  RETURN OLD;
END;
$$;

To run this after deletes:

CREATE TRIGGER Question_delete_trig
  AFTER DELETE ON Question
  FOR EACH ROW EXECUTE PROCEDURE Question_delete_trig_func();

That should be enough to get you started.

You should have a trigger like this for each table from which deleted rows should be saved. Then you need to determine how you will make the deletes happen. You could just define the appropriate foreign keys as ON DELETE CASCADE and let PostgreSQL do it for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM