簡體   English   中英

ER上的PostgreSQL更正觸發器

[英]PostgreSQL from E-R to correct trigger

我有這個ER圖: E-R圖 我已經完成了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)
);

注意: 斜體的屬性是外鍵, 粗體主鍵。

  • Utente( ID_Utente ,用戶名)
  • 巴切卡( ID_BachecaID_Proprietario ,Titolo,N_follower)
  • 想象ID_img ,Origine, DescrizioneBachecaPossessore ,N_pin,N_like,N_preferiti, ID_PreferitoOrigine∈ {UPLOAD,LINK} Descrizione可以為NULL
  • 主題( ID_topic ,Nome)
  • Correlazione(想象,題目
  • 別針( Utente,想象
  • 喜歡( Utente,想象
  • 跟隨巴切卡( Utente,巴切卡
  • FollowUtenti( 關注者,已關注
  • Attinenza( 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM