Mysql

MySQL 觸發器可以包含 where 子句嗎

  • August 23, 2019

我需要創建一個觸發器,只要山羊的sireRegNo 列更新,它的sireName 列就會自動更新以匹配。

我有一個儲存動物家譜的數據庫。每行都儲存其父母雙方的姓名和註冊編號。SireName 欄位是只讀的,但註冊商可以更改sireRegno。

創建語句:

CREATE TABLE `table_name` (
   `id_goat` int(11) NOT NULL AUTO_INCREMENT,
   `name` varchar(80) NOT NULL,
   `regNo` varchar(50) DEFAULT '',
   `sireName` varchar(80) DEFAULT NULL,
   `sireRegNo` varchar(50) DEFAULT '',
   PRIMARY KEY (`id_goat`,`name`),
   UNIQUE KEY `id_goat_UNIQUE` (`id_goat`),
   UNIQUE KEY `name_UNIQUE` (`name`),
   UNIQUE KEY `regNo_UNIQUE` (`regNo`)
) ENGINE=InnoDB AUTO_INCREMENT=188784 DEFAULT CHARSET=utf8;

範例數據:

table_name

name    |   regNo   |   sireName    | sireRegNo
----------------------------------------------
Old Man |   2048    |   Methusela   |   9999
Daddy   |   1234    |   Grandpa     |   4321
Kid     |   9191    |   Daddy       |   1234

免責聲明:是的,我知道這沒有標準化。我試過在 regno 上加入,發現它花了很長時間。原因是,我認為,我們有一個搜尋頁面,它使用 DataTables 載入數據庫中的每一行(不過,只有每個行的公共數據)。它不會一次全部顯示,而是載入它,因此它可以使用搜尋輸入在客戶端過濾它們。所以我們基本上是在嘗試將整個表加入到自身中,每頁載入大約需要 30 秒。

我知道我可能以某種方式做錯了什麼,並且有一種方法可以“正確”地做到這一點,但這不是我在這裡要問的。即便如此,我們也歡迎為此提供答案。

Kid 現在是個十幾歲的孩子,他堅持認為有人將他錯誤地放入數據庫中,並且他的親生父親是老人,regno 2048。

那麼我的問題 - 我可以觸發,當註冊商將 Kid’s SireRegNo 更改為 2048 時,Kid’s SireName 列會更改為“Old Man”?

觸發版本(對此最不滿意,對其他人來說最不確定)

這是我對“實際”觸發器的嘗試,以防觸發器和儲存過程之間存在一些顯著差異。從本頁中途修改

mysql> delimiter //
mysql> CREATE TRIGGER update_sire_name BEFORE UPDATE ON table_name
   -> FOR EACH ROW #I trust this means "each row that is modified"...
   -> BEGIN
   ->     IF NEW.sireRegNo = table_name.regNo THEN #searches regNo field of every row in DB for the new value stored in sireRegNo
   ->         SET NEW.sireName = table_name.name
   ->     END IF;
   -> END;//
mysql> delimiter ;

儲存過程版本(更舒適,可能離我需要的更遠?)

從此頁面修改

DELIMITER //
CREATE PROCEDURE sp3
(IN reg CHAR(50))
BEGIN
   SELECT name FROM goatdata
   WHERE regno = NEW.reg;
   SET NEW.sireName = 'result of above SELECT statement'
END //
DELIMITER ;

我以前沒有處理過觸發器或儲存過程,所以這對我來說看起來很奇怪,並且可能在多個方面都是錯誤的。另外,我意識到這是針對儲存過程的,但是正如我一直在搜尋的那樣,我在某處看到觸發器是儲存過程,所以我希望這很清楚,甚至我可以將“程序”替換為“扳機”?也許?無論如何,它確實感覺更接近我想要做的事情。

REGULAR MYSQL(對我來說最清楚,但顯然不是我需要的)

SELECT name, regno FROM table_name WHERE regno = 'correct sire regno';
UPDATE table_name SET sireName = 'correct sire name' WHERE regno = 'kid regno'

您快到了。您的觸發器應該如下所示:

CREATE TRIGGER update_sire_name before UPDATE ON table_name
for each row

   set new.sireName = 
   (select name from table_name where regNo = new.sireRegNo)

小提琴手


1是的,觸發器中可以有where子句。

2考慮使用數值數據類型(例如INTEGER),其中值明顯是數字(例如regNo

引用自:https://dba.stackexchange.com/questions/246014