2013-07-24 82 views
1

我是MySQL和SQL新手,我剛剛發現MySQL不支持斷言。MySQL聲明

我有這些表:


create table stagione 
    (
    nome   varchar(20), 
    biennio  char(9), 
    teatro   varchar(20), 
    primary key(nome, biennio), 
    foreign key (teatro) references teatro(nome) 
on update cascade on delete set null 
) 
    ENGINE=InnoDB; 

create table produzione 
    (
    produttore  varchar(20), 
    spettacolo  varchar(40), 
    primary key(produttore, spettacolo), 
    foreign key (produttore) references produttore(nome) 
       on update cascade on delete cascade, 
    foreign key (spettacolo) references spettacolo(titolo) 
       on update cascade on delete cascade
) ENGINE=InnoDB;

create table proposta 
    (
    nomeStagione varchar(20), 
    biennioStagione char(9), 
    spettacolo varchar(40), 
    primary key(nomeStagione, biennioStagione, spettacolo), 
    foreign key (nomeStagione, biennioStagione) references stagione(nome, biennio) 
on update cascade on delete cascade, 
    foreign key (spettacolo) references spettacolo(titolo) 
on update cascade on delete cascade 
) 
ENGINE=InnoDB; 

與MySQL我沒有寫聲明的方式。是否可以使用一個或多個觸發器模擬以下斷言?


crate assertion RA2 check (
    not exists (
     select stagione.teatro, stagione.nome, stagione.biennio, count(*) 
     from (stagione join proposta on 
      (stagione.nome = proposta.nomeStagione) and 
      (stagione.biennio = proposta.biennioStagione)) 
      join produzione on 
      (proposta.spettacolo = produzione.spettacolo) and 
      (stagione.teatro = produzione.produttore) 
     group by stagione.teatro, stagione.nome, stagione.biennio 
     having count(*) > 2 
    ) 
);   

我該怎麼寫這個觸發器?

+0

你能用簡單的話來解釋你到底想要達到什麼目的嗎? – peterm

+1

該斷言所指的規則是:劇院(劇院)不能在同一戲劇季節(劇情)中放映超過兩部戲劇(劇集)的自己製作(劇集) – user2610920

回答

2

如果我理解正確的模式,那麼你可以通過觸發器這樣

CREATE TRIGGER tg_proposta_before_insert 
BEFORE INSERT ON proposta 
FOR EACH ROW 
    SET NEW.nomeStagione = IF(
    (
     SELECT COUNT(*) total 
     FROM proposta p JOIN produzione d 
      ON p.spettacolo = d.spettacolo 
     WHERE p.nomeStagione = NEW.nomeStagione 
     AND p.biennioStagione = NEW.biennioStagione 
     AND d.produttore = 
      (
       SELECT produttore 
       FROM produzione 
       WHERE spettacolo = NEW.spettacolo 
       LIMIT 1 
      ) 
    ) < 2, 
    NEW.nomeStagione, 
    NULL 
); 

執行您的規則爲使其在proposta表工作你必須有NOT NULL約束上nomeStagione列。 你最好對所有列這樣的約束是參與主鍵反正

一些解釋:

  1. 這是一個BEFORE觸發器,因爲它是在MySQL中唯一的事件中,你可以改變的列值插入一行。您使用NEW關鍵字訪問這些值。
  2. 現在,當您嘗試插入一行到proposta它會檢查是否已經有兩場戲爲同一劇場出演其中的你試圖插入違反了nomeStagione柱(NOT NULL約束它可以是任何其他列 )有效地防止該插入完成。

這裏是SQLFiddle演示。 嘗試取消最後一條插入語句和Build Schema的註釋。你會看到它不會讓你插入那一行。這將是這個劇場的第三場戲劇,在這個季節

+1

問題。不要使主鍵強制執行** NOT NULL **約束? – pratnala

+0

如果您在插入之前使用過程來檢查,會不會更好? – Melanef