[英]PostgreSQL from E-R to correct trigger
我有這個ER圖: 我已經完成了SQL翻譯,並以這種方式編寫了所有關系:
CREATE DOMAIN origine
AS VARCHAR(6) DEFAULT NULL
CHECK (value ='upload' or value = 'link');
CREATE TABLE progetto.Utente (
ID_Utente VARCHAR(4) check (ID_Utente like ‘U%’),
PRIMARY KEY (ID_Utente),
Username VARCHAR(20) NOT NULL UNIQUE
);
CREATE INDEX progetto.IDX_Utente_ID_Utente
ON progetto.Utente (ID_Utente);
CREATE TABLE progetto.Bacheca (
ID_Bacheca VARCHAR(4) check (ID_Bacheca like ‘B%’),
ID_Proprietario VARCHAR(4) NOT NULL,
PRIMARY KEY (ID_Bacheca),
FOREIGN KEY (ID_Proprietario) references progetto.Utente (ID_Utente)
on update cascade
on delete cascade,
Titolo VARCHAR(20) NOT NULL,
N_follower INT
);
CREATE TABLE progetto.Immagine (
ID_Img VARCHAR(4) check (ID_Img like ‘I%’),
PRIMARY KEY (ID_Img),
Origine origine,
Descrizione VARCHAR(20) default NULL,
Bacheca VARCHAR(4) NOT NULL,
FOREIGN KEY (Bacheca) references progetto.Bacheca (ID_Bacheca)
on update cascade
on delete cascade,
Possessore VARCHAR(4) NOT NULL,
FOREIGN KEY (Possessore) references progetto.Utente (ID_Utente)
on update cascade
on delete cascade
N_pin INT NOT NULL,
N_like INT NOT NULL,
N_preferiti INT NOT NULL,
ID_Preferito VARCHAR (20) NOT NULL
FOREIGN KEY (ID_Preferito) references progetto.Utente (ID_Utente)
on update cascade
on delete cascade
);
CREATE TABLE progetto.Topic (
ID_topic VARCHAR(4) check (ID_topic like ‘T%’),
PRIMARY KEY (ID_topic),
Nome VARCHAR(20) NOT NULL
);
CREATE TABLE progetto.Correlazione (
Immagine VARCHAR(4) NOT NULL,
FOREIGN KEY (Immagine) references progetto.Immagine (ID_Img)
on update cascade
on delete cascade,
Topic VARCHAR(20) NOT NULL,
FOREIGN KEY (Topic) references progetto.Topic (ID_topic)
on update cascade
on delete cascade,
PRIMARY KEY (Immagine, Topic)
);
CREATE TABLE progetto.Pin (
Utente VARCHAR(4) NOT NULL,
FOREIGN KEY (Utente) references progetto.Utente (ID_Utente)
on update cascade
on delete cascade,
Immagine VARCHAR(20) NOT NULL,
FOREIGN KEY (Immagine) references progetto.Immagine (ID_Img)
on update cascade
on delete cascade,
PRIMARY KEY (Utente, Immagine)
);
CREATE TABLE progetto.Likes (
Utente VARCHAR(4) NOT NULL,
FOREIGN KEY (Utente) references progetto.Utente (ID_Utente)
on update cascade
on delete cascade,
Immagine VARCHAR(20) NOT NULL,
FOREIGN KEY (Immagine) references progetto.Immagine (ID_Img)
on update cascade
on delete cascade,
PRIMARY KEY (Utente, Immagine)
);
CREATE TABLE progetto.FollowBacheca (
Utente VARCHAR(4) NOT NULL,
FOREIGN KEY (Utente) references progetto.Utente (ID_Utente)
on update cascade
on delete cascade,
Bacheca VARCHAR(4) NOT NULL,
FOREIGN KEY (Bacheca) references progetto.Bacheca (ID_Bacheca)
on update cascade
on delete cascade,
PRIMARY KEY (Utente, Bacheca)
);
CREATE TABLE progetto.FollowUtenti (
Follower VARCHAR(4),
FOREIGN KEY (Follower) references progetto.Utente (ID_Utente)
on update cascade
on delete cascade,
Followed VARCHAR(4),
FOREIGN KEY (Followed) references progetto.Utente (ID_Utente)
on update cascade
on delete cascade,
PRIMARY KEY (Follower, Followed)
);
CREATE TABLE progetto.Affinità (
Topic1 VARCHAR(4) NOT NULL,
FOREIGN KEY (Topic1) references progetto.Topic (ID_topic)
on update cascade
on delete cascade,
Topic2 VARCHAR(4) NOT NULL,
FOREIGN KEY (Topic2) references progetto.Topic (ID_topic)
on update cascade
on delete cascade,
PRIMARY KEY (Topic1, Topic2)
);
注意: 斜體的屬性是外鍵, 粗體主鍵。
現在我有一個問題。 我希望,當我刪除與“ Possesso”有關系的“ Immagine”的“ Utente”(用戶)時,僅當“ Immagine”的原點為“ link”時才刪除。
我認為我必須使用觸發器,但是我無法編寫一個可以觸發的觸發器。 有什么建議么?
PS:對意大利的名字感到抱歉。
是的,您應該使用觸發器來解決此問題。 但是首先,您應該從Immagine
表中刪除ON DELETE CASCADE
子句:
possessore varchar(4) NOT NULL REFERENCES progetto.Utente ON UPDATE CASCADE
如果origine = 'link'
並且表Pin
中沒有將圖像鏈接到用戶的行,則觸發函數將在表Immagine
中進行刪除。 請注意,這假設每個Utente僅有一個Immagine。
CREATE FUNCTION progetto.delete_immagine_origine_link() RETURNS trigger AS $$
DECLARE
id_immagine varchar(4);
org origine;
BEGIN
-- Check if an Immagine is linked to the Utente
SELECT ID_Img, Origine INTO id_immagine, org
FROM progetto.Immagine
WHERE possessore = OLD.ID_Utente;
IF FOUND THEN
-- There is a row, but if the origine is wrong, fail the delete
IF org != 'link' THEN
RETURN NULL;
END IF;
-- Now check if there is a Pin row that links Immagine to Utente
PERFORM * FROM progetto.Pin
WHERE Utente = OLD.ID_Utente AND Immagine = id_immagine;
IF FOUND THEN
RETURN NULL; -- There is a link, fail the delete
END IF;
-- It is safe to delete the row from Immagine
DELETE FROM progetto.Immagine
WHERE ID_Img = id_immagine;
END IF;
-- Either there was no Immagine for the Utente or it has been deleted
-- so safe to delete Utente
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
觸發器本身應在Utente
表上定義:
CREATE TRIGGER delete_from_utente
BEFORE DELETE ON progetto.Utente
FOR EACH ROW EXECUTE PROCEDURE progetto.delete_immagine_origine_link();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.