我有以下表格:
CREATE TABLE QUESTION(
id varchar(10) NOT NULL PRIMARY KEY,
que_type numeric(1));
CREATE TABLE ESSAY(
que_id varchar(10) NOT NULL PRIMARY KEY,
ans varchar(2000),
FOREIGN KEY (que_id) REFERENCES QUESTION (id));
CREATE TABLE TFFB(
que_id varchar(10) NOT NULL PRIMARY KEY,
ans varchar(50),
FOREIGN KEY (que_id) REFERENCES QUESTION (id));
CREATE TABLE MCQ(
que_id varchar(10) NOT NULL PRIMARY KEY,
ans varchar(200),
FOREIGN KEY (que_id) REFERENCES QUESTION (id));
并尝试创建触发器,以便当我从主表中删除时,它将从其他表中删除相关的行:
CREATE OR REPLACE FUNCTION delete_question()
RETURNS trigger AS $delete_question$
DECLARE
BEGIN
IF ( (OLD).que_type = '1' ) THEN
IF EXISTS (SELECT 1 FROM mcq WHERE person_id = (OLD).id) THEN
DELETE FROM mcq WHERE que_id='(OLD).id';
END IF;
ELSIF ( (OLD).que_type = '2' OR OLD.que_type = '3' ) THEN
IF EXISTS (SELECT 1 FROM tffb WHERE person_id = (OLD).id) THEN
DELETE FROM tffb WHERE que_id='(OLD).id';
END IF;
ELSIF ( (OLD).que_type = '4' ) THEN
IF EXISTS (SELECT 1 FROM essay WHERE person_id = (OLD).id) THEN
DELETE FROM essay WHERE que_id='(OLD).id';
END IF;
END IF;
RETURN NULL;
END;
$delete_question$ LANGUAGE plpgsql;
CREATE TRIGGER delete_question
BEFORE DELETE ON question
FOR EACH ROW EXECUTE PROCEDURE delete_question();
当我从question
删除数据时,该行会消失一段时间。但是当我刷新时,它仍然在那里
我试图放RETURN OLD;
但由于约束关系而失败了。
这有什么问题?
答案 0 :(得分:2)
关于触发功能的更多建议:
CREATE OR REPLACE FUNCTION delete_question()
RETURNS trigger AS
$func$
BEGIN
CASE OLD.que_type
WHEN 1 THEN
DELETE FROM mcq WHERE que_id=OLD.id;
WHEN 2, 3 THEN
DELETE FROM tffb WHERE que_id=OLD.id;
WHEN 4 THEN
DELETE FROM essay WHERE que_id=OLD.id;
-- ELSE
-- Do something?
END CASE;
RETURN OLD;
END
$func$ LANGUAGE plpgsql;
使用SELECT
语句检查是否存在会使费用增加一倍。只需运行DELETE
,如果找不到匹配的行,则不删除任何内容。
在此处使用CASE
声明。更短,更快。请注意,plpgsql CASE
与SQL CASE
语句略有不同。例如,您可以一次列出几个案例。
除非您实际声明变量,否则不需要DECLARE
关键字。
您可以cascading deletes via foreign key完全避免问题,@a_horse mentioned in the comment。我的架构布局如下所示:
CREATE TABLE question (
question_id serial NOT NULL PRIMARY KEY
,que_type int -- this may be redundant as well
);
CREATE TABLE essay (
que_id int NOT NULL PRIMARY KEY
REFERNECES question(question_id) ON UPDATE CASCADE
ON DELETE CASCADE
,ans text
);
...
关于serial
:
Auto increment SQL function
答案 1 :(得分:1)
CREATE OR REPLACE FUNCTION delete_question()
RETURNS trigger AS $delete_question$
DECLARE
BEGIN
IF ( OLD.que_type=1 ) THEN
IF EXISTS (SELECT 1 FROM mcq WHERE que_id=OLD.id) THEN
DELETE FROM mcq WHERE que_id=OLD.id;
END IF;
ELSIF ( OLD.que_type=2 OR OLD.que_type=3) THEN
IF EXISTS (SELECT 1 FROM tffb WHERE que_id=OLD.id) THEN
DELETE FROM tffb WHERE que_id=OLD.id;
END IF;
ELSIF ( OLD.que_type=4 ) THEN
IF EXISTS (SELECT 1 FROM essay WHERE que_id=OLD.id) THEN
DELETE FROM essay WHERE que_id=OLD.id;
END IF;
END IF;
RETURN OLD;
END;
$delete_question$ LANGUAGE plpgsql;
CREATE TRIGGER delete_question
BEFORE DELETE ON question
FOR EACH ROW EXECUTE PROCEDURE delete_question();
' '
甚至OLD.id
上没有(OLD).id
并使用RETURN OLD;