MySQL觸發器


        觸發器是一種特殊的存儲過程,是嵌入到mysql的一段程序,它在插入,刪除或修改特定表中的數據時觸發執行。

        數據庫觸發器有以下的作用:

1.安全性。可以基於數據庫的值使用戶具有操作數據庫的某種權利,允許或限制對表的修改:

         # 可以基於時間限制用戶的操作,例如不允許下班后和節假日修改數據庫數據。

         # 可以基於數據庫中的數據限制用戶的操作,例如不允許股票的價格的升幅一次超過10%。

2.提供審計和日志記錄。例:跟蹤用戶對數據庫的操作。   

         # 審計用戶操作數據庫的語句。

         # 把用戶對數據庫的更新寫入審計表,更新日志記錄。

3.實現復雜的數據完整性規則

         # 實現非標准的數據完整性檢查和約束。觸發器可產生比規則更為復雜的限制。與規則不同,觸發器可以引用列或數據庫對象。例如,觸發器可回退任何企圖吃進超過自己保證金的期貨。

          # 提供可變的缺省值。

4.實現強制數據的一致性規則。觸發器可以對數據庫中相關的表進行連環更新。例如,在auths表author_code列上的刪除觸發器可導致相應刪除在其它表中的與之匹配的行。

          # 在修改或刪除時級聯修改或刪除其它表中的與之匹配的行。

          # 在修改或刪除時把其它表中的與之匹配的行設成NULL值。

          # 在修改或刪除時把其它表中的與之匹配的行級聯設成缺省值。

          # 觸發器能夠拒絕或回退那些破壞相關完整性的變化,取消試圖進行數據更新的事務。當插入一個與其主健不匹配的外部鍵時,這種觸發器會起作用。例如,可以在books.author_code 列上生成一個插入觸發器,如果新值與auths.author_code列中的某值不匹配時,插入被回退。

5.同步實時地復制表中的數據。

6.自動計算數據值,如果數據的值達到了一定的要求,則進行特定的處理。例如,如果公司的帳號上的資金低於5萬元則立即給財務人員發送警告數據。

7.自動派生列,如自增字段

8.啟動復雜的業務邏輯,防止無效的事務處理

數據完整性(Data Integrity是指數據的精確性(Accuracy) 和可靠性(Reliability)。它是應防止數據庫中存在不符合語義規定的數據和防止因錯誤信息的輸入輸出造成無效操作或錯誤信息而提出的。

數據庫一致性(Database Consistency是指事務執行的結果必須是使數據庫從一個一致性狀態變到另一個一致性狀態。保證數據庫一致性是指當事務完成時,必須使所有數據都具有一致的狀態。在關系型數據庫中,所有的規則必須應用到事務的修改上,以便維護所有數據的完整性。

 

通常觸發器具有四要素:

   • 監視地點:監視的哪個表?

   •監視操作:insert,update,delete?

   •觸發操作:insert,update,delete?

   •觸發時間:after,before?

 

Mysql觸發器的使用

1)Mysql創建觸發器
        create trigger <觸發器名稱> { before | after} {insert | update | delete} on <表名> for each row <觸發器SQL語句>
        create trigger <觸發器名稱>:創建一個新觸發器,並指定觸發器的名稱。
        { before | after}:用於指定在insert、update或delete語句執行前觸發還是在語句執行后觸發。
        on <表名>:用於指定響應該觸發器的表名。
        for each row:觸發器的執行間隔,for each row 通知觸發器每隔一行執行一次動作,而不是對整個表執行一次。
        <觸發器SQL語句>:觸發器要執行的SQL語句,如果該觸發器要執行多條SQL語句,要將多條語句放在begin…end塊中。

 

2)Mysql查看觸發器

        如果知道觸發器所在數據庫,以及觸發器名稱等具體信息:
              SHOW TRIGGERS from 庫名 like "觸發器名%";
         如果不了解觸發器的具體的信息,或者需要查看數據庫上所有觸發器,如下:
                SHOW TRIGGERS;       //查看所有觸發器
          用上述方式查看觸發器可以看到數據庫的所有觸發器,也可以通過information_schema.TRIGGERS表查看:(information_schema.TRIGGERS表,存儲所有庫中的所有觸發器)
           select * from information_schema. TRIGGERS where TRIGGER_NAME= '觸發器名' \G;

3)刪除觸發器
           DROP TRIGGER [schema_name.]trigger_name

 

4)觸發器類型

        在一個表上最多建立6個觸發器,即(1)before insert型、(2)before update型、(3)before delete型、(4)after insert型、(5)after update型、(6)after delete型。
        觸發器的一個限制是不能同時在一個表上建立2個相同類型的觸發器。這個限制的一個來源是觸發器程序體的“begin和end之間允許運行多個語句”(摘自mysql使用手冊)。
         另外還有一點需要注意,msyql除了對insert,update,delete基本操作進行定義外,還定義了load data和replace語句,而load data和replace語句也能引起上述6中類型的觸發器的觸發。
          Load data語句用於將一個文件裝入到一個數據表中,相當與一系列insert操作。replace語句一般來說和insert語句很像,只是在表中有 primary key和unique索引時,如果插入的數據和原來primary key和unique索引一致時,會先刪除原來的數據,然后增加一條新數據;也就是說,一條replace sql有時候等價於一條insert sql,有時候等價於一條delete sql加上一條insert sql。即是:
    •   Insert型觸發器:可能通過insert語句,load data語句,replace語句觸發;
    •   Update型觸發器:可能通過update語句觸發;
    •   Delete型觸發器:可能通過delete語句,replace語句觸發;

 

          觸發程序不能調用將數據返回客戶端的存儲程序,也不能使用采用CALL語句的動態SQL
(允許存儲程序通過參數將數據返回觸發程序)。
          觸發程序不能使用以顯式或隱式方式開始或結束事務的語句,如START TRANSACTION、
COMMIT或ROLLBACK。

          使用OLD和NEW關鍵字,能夠訪問受觸發程序影響的行中的列(OLD和NEW不區分大小寫)。
          在INSERT觸發程序中,僅能使用NEW.col_name,沒有舊行。在DELETE觸發程序中,僅能使用OLD.col_name,沒有新行。在UPDATE觸發程序中,可以使用OLD.col_name來引用更新前的某一行的列,也能使用NEW.col_name來引用更新后的行中的列。
          用OLD命名的列是只讀的。你可以引用它,但不能更改它。對於用NEW命名的列,如果具有SELECT權限,可引用它。在BEFORE觸發程序中,如果你具有UPDATE權限,可使用“SET NEW.col_name = value”更改它的值。這意味着,你可以使用觸發程序來更改將要插入到新行中的值,或用於更新行的值。

        在BEFORE觸發程序中,AUTO_INCREMENT列的NEW值為0,不是實際插入新記錄時將自動生成的序列號。

        通過使用BEGIN ... END結構,能夠定義執行多條語句的觸發程序。在BEGIN塊中,還能使用存儲子程序中允許的其他語法,如條件和循環等。

例1:在before update中使用NEW和OLD關鍵字

i. 建立觸發器:

mysql> delimiter //

mysql> create trigger trigger_before_tb_update before update on tb for each row

    -> begin

    ->   insert into tb11 values(1, old.name, 20);

    ->   insert into tb11 values(2, new.name, 22);

    -> end

    -> //

mysql> delimiter ;

 

ii. 查看數據表

mysql> select * from tb;

+------+------+-----+

| id   | Name | Age |

+------+------+-----+

|    1 | aa   |  20 |

| 1001 | dd   |  20 |

+------+------+-----+

2 rows in set (0.00 sec)

 

mysql> select * from tb11;

Empty set (0.02 sec)

 

iii. 執行sql:

mysql> update tb set name='bb' where id=1;   //觸發觸發器執行

Query OK, 1 row affected (0.06 sec)

Rows matched: 1  Changed: 1  Warnings: 0

 

iv. 再次查看

mysql> select * from tb;

+------+------+-----+

| id   | Name | Age |

+------+------+-----+

|    1 | bb   |  20 |

| 1001 | dd   |  20 |

+------+------+-----+

2 rows in set (0.00 sec)

 

mysql> select * from tb11;

+------+------+-----+

| id   | Name | Age |

+------+------+-----+

|    1 | aa   |  20 |

|    2 | bb   |  22 |

+------+------+-----+

2 rows in set (0.00 sec)

 

可以看到,OLD和NEW分別代表執行update操作前后的值。

 

例2:在after update中使用NEW和OLD關鍵字

i. 建立觸發器:

mysql> delimiter //

mysql> create trigger trigger_after_tb_update after update on tb for each row

    -> begin

    ->   insert into tb11 values(1, old.name, 20);

    ->   insert into tb11 values(2, new.name, 22);

    -> end

    -> //

mysql> delimiter ;

 

ii. 查看數據表

mysql> select * from tb;

+------+------+-----+

| id   | Name | Age |

+------+------+-----+

|    1 | bb   |  20 |

| 1001 | dd   |  20 |

+------+------+-----+

2 rows in set (0.00 sec)

 

mysql> select * from tb11;

Empty set (0.00 sec)

 

iii. 執行sql:

mysql> update tb set name='aa' where id=1;   //觸發觸發器執行

Query OK, 1 row affected (0.05 sec)

Rows matched: 1  Changed: 1  Warnings: 0

 

iv. 再次查看

mysql> select * from tb;

+------+------+-----+

| id   | Name | Age |

+------+------+-----+

|    1 | aa   |  20 |

| 1001 | dd   |  20 |

+------+------+-----+

2 rows in set (0.00 sec)

 

mysql> select * from tb11;

+----+------+-----+

| id | Name | Age |

+----+------+-----+

|  1 | bb   |  20 |

|  2 | aa   |  22 |

+----+------+-----+

2 rows in set (0.00 sec)

 

同樣可以看到,OLD和NEW分別代表執行update操作前后的值。

 

例3.在觸發器中更改NEW的值

i. 建立觸發器:

mysql> delimiter //

mysql> create trigger trigger_before_tb_update before update on tb for each row

    -> begin

    ->   insert into tb11 values(1, old.name, 20);

    ->   set new.name = 'changename';

    ->   insert into tb11 values(2, new.name, 22);

    -> end

    -> //

mysql> delimiter ;

 

ii. 查看數據表

mysql> select * from tb;

+----+------+-----+

| id | Name | Age |

+----+------+-----+

|  1 | aa   |  20 |

+----+------+-----+

1 row in set (0.00 sec)

 

mysql> select * from tb11;

Empty set (0.00 sec)

 

iii. 執行sql:

mysql> update tb set name='bb' where id=1;   //觸發觸發器執行

Query OK, 1 row affected (0.06 sec)

Rows matched: 1  Changed: 1  Warnings: 0

 

iv. 再次查看

mysql> select * from tb;

+----+------------+-----+

| id | Name       | Age |

+----+------------+-----+

|  1 | changename |  20 |

+----+------------+-----+

1 row in set (0.00 sec)

 

mysql> select * from tb11;

+----+------------+-----+

| id | Name       | Age |

+----+------------+-----+

|  1 | aa         |  20 |

|  2 | changename |  22 |

+----+------------+-----+

2 rows in set (0.00 sec)

 

可以看到,在觸發器中更新NEW的值,將直接影響到觸發表中的更新。

 

例4.在after update中嘗試修改NEW值

i. 建立觸發器:

mysql> delimiter //

mysql> create trigger trigger_after_tb_update after update on tb for each row

    -> begin

    ->   insert into tb11 values(1, old.name, 20);

    ->   set new.name = 'changename';

    ->   insert into tb11 values(2, new.name, 22);

    -> end

    -> //

ERROR 1362 (HY000): Updating of NEW row is not allowed in after trigger

mysql> delimiter ;

 

可以看到,在after update類型觸發器中不允許修改NEW值。

 

3   Mysql觸發器的執行順序
        先拋出觸發器相關的幾個問題
3.1   如果before類型的觸發器程序執行失敗,sql會執行成功嗎?
實驗如下:
1)建立before觸發器:

mysql> delimiter //

mysql> create trigger trigger_before_tb_update before update on tb for each row

    -> begin

    -> insert into tbx values(2, 'trigger_before', 22);

    -> end

    -> //

mysql> delimiter ;


2)查看:

mysql> select * from tb;

+------+--------+-----+

| id   | Name   | Age |

+------+--------+-----+

|    1 | tejevo |  20 |

| 1001 | dd     |  20 |

+------+--------+-----+


3)執行sql:

mysql> update tb set name='aa' where id=1;       觸發觸發器程序;

4)由於不存在tbx,before觸發器執行失敗,提示:
ERROR 1146 (42S02): Table 'testdb.tbx' doesn't exist


5)再次查看:
mysql> select * from tb where id=1;

+----+--------+-----+

| id | Name   | Age |

+----+--------+-----+

|  1 | tejevo |  20 |

+----+--------+-----+

修改sql未執行成功。即如果before觸發器執行失敗,sql也會執行失敗。

3.2   如果sql執行失敗,會執行after類型的觸發器程序嗎?
實驗如下:
1)建立after觸發器:
mysql> delimiter //

mysql> create trigger trigger_after_tb_update after update on tb for each row

    -> begin

    -> insert into tb11(id, name, age, sex) values(2, 'bb', 20, m);

    -> end

    -> //

mysql> delimiter ;



2)查看觸發表:
mysql> select * from tb11;

Empty set (0.05 sec)

沒有記錄


3)執行sql:
mysql> update tb set name='aa' where id=1;       觸發觸發器程序;

4)由於不存在sex列,提示錯誤:
ERROR 1054 (42S22): Unknown column 'sex' in 'field list'


5)再次查看觸發表:
mysql> select * from tb11;

Empty set (0.00 sec)
沒有記錄。

sql在執行失敗時,after型觸發器不會執行。

3.3   如果after類型的觸發器程序執行失敗,sql會回滾嗎?
實驗如下:
1)建立after觸發器:
mysql> select * from tb11;

Empty set (0.00 sec)


2)查看:

mysql> select * from tb;

+------+--------+-----+

| id   | Name   | Age |

+------+--------+-----+

|    1 | tejevo |  20 |

| 1001 | dd     |  20 |

+------+--------+-----+

2 rows in set (0.00 sec)

 
3)執行sql:
mysql> update tb set name='aa' where id=1;       觸發觸發器程序;


4)由於不存在sex列,提示錯誤:
ERROR 1054 (42S22): Unknown column 'sex' in 'field list'

 

5)再次查看:
mysql> select * from tb;

+------+--------+-----+

| id   | Name   | Age |

+------+--------+-----+

|    1 | tejevo |  20 |

| 1001 | dd     |  20 |

+------+--------+-----+

2 rows in set (0.00 sec)

即修改sql未執行成功。即如果after觸發器執行失敗,sql會回滾。

注:上述實驗所使用的mysql引擎是innodb。

         “對於事務性表,如果觸發程序失敗(以及由此導致的整個語句的失敗),該語句所執行的所有更改將回滾。對於非事務性表,不能執行這類回滾”(摘自mysql使用手冊)。因而,即使語句失敗,失敗之前所作的任何更改依然有效,也就是說,對於 innodb引擎上的數據表,如果觸發器中的sql或引發觸發器的sql執行失效,則事務回滾,所有操作會失效。
        對於事務性表,如果觸發程序失敗(以及由此導致的整個語句的失敗),該語句所執行的所有更改將回滾。對於非事務性表,不能執行這類回滾,因而,即使語句失敗,失敗之前所作的任何更改依然有效。


3.4   mysql觸發器程序執行的順序
        當一個表既有before類型的觸發器,又有after類型的觸發器時;當一條sql語句涉及多個表的update時,sql、觸發器的執行順序經過mysql源碼包裝過,有時比較復雜。
        可以先看一段mysql的源代碼,當SQL中update多表的時候,Mysql的執行過程如下(省去了無關代碼):

/* 遍歷要更新的所有表 */
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
{
    org_updated = updated
    /* 如果有 BEFORE 觸發器,則執行;如果執行失敗,跳到err2位置 */
    if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,TRG_ACTION_BEFORE, TRUE))
        goto err2;
    /*執行更新,如果更新失敗,跳到err位置*/
    if(local_error=table->file->update_row(table->record[1], table->record[0])))
        goto err;
    updated++; // 更新計數器
    /* 如果有 AFTER 觸發器,則執行;如果執行失敗,跳到err2位置*/
    if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE))
        goto err2;
    err:
    {
        /*標志錯誤信息,寫日志等*/
    }
    err2:
    {
        /*恢復執行過的操作*/
        check_opt_it.rewind();
        /*如果執行了更新,且表是有事務的,做標志*/
        if (updated != org_updated)
        {
            if (table->file->has_transactions())
                transactional_tables= 1;
            }
        }
    }

        從上面代碼可以找到本章開始時拋出問題的答案。
1)   如果before型觸發器執行失敗,直接goto跳到err2位置,不會執行后續sql語句;
2)   如果sql執行失敗,直接goto跳到err位置,不會執行或許的after型觸發器;
3)   如過after觸發器執行失敗,goto到err2位置,恢復執行過的操作,且在事務型的表上做標記。
        另外,在使用復雜的sql時,由於有些復雜的sql是mysql自己定義的,所以存在不確定性,使用簡單的sql比較可控。

4   Mysql觸發器在數據庫同步中的表現
4.1   觸發器運行失敗時,數據庫同步會失敗嗎?
        有同步關系如下dbA?dbB。初始時同步正常。

1)在dbB上建立觸發器:

mysql> delimiter //

mysql> create trigger trigger_before_tb_update before update on tb for each row

    -> begin

    -> insert into tbx values(2, 'trigger_before', 22);

    -> end

    -> //

mysql> delimiter ;

 

2) 查看:

mysql> select * from dbA.tb;

+------+------+-----+

| id   | Name | Age |

+------+------+-----+

|    1 | aa   |  20 |

| 1001 | dd   |  20 |

+------+------+-----+

2 rows in set (0.00 sec)

 

3)在dbA上執行sql,執行成功;
mysql> update tb set name='bb' where id=1;       觸發觸發器程序;


4)由於dbB上沒有tbx表,觸發器會執行失敗,這時,檢查一下同步狀態:

Slave_IO_Running: Yes
Slave_SQL_Running: NO
Last_Errno: 1146
Last_Error: Error 'Table 'tbx' doesn't exist' on query.


        可以看到IO線程運行正常,sql線程運行失敗,並提示觸發器運行失敗的錯誤信息。

        無論是before部分的觸發器還是after類型的觸發器,對於innodb引擎,當觸發器執行失敗時,相應sql也會執行失敗,所以數據庫同步也會失敗。

4.2   創建、刪除觸發器寫bin-log
        創建和刪除觸發器的語句也會寫入bin-log里,所以也會如一般的insert,update,delete語句一樣同步到下游數據庫中,即上游創建觸發器,下游也會創建。
        這里再引出兩個小問題:有同步關系dbA?dbB,
1)   在dbA上創建一個觸發器,如果dbB上已經有同表同類型的觸發器,同步狀態如何?
2)   在dbB上刪除一個觸發器,如果dbB上沒有對應觸發器,同步狀態如何?
        這兩個問題可以類比同步中的insert語句和delete語句,答案就是
1)   同步失敗,因為不允許重復創建同表同類型的觸發器;
2)   同步正常,因為drop一個不存在的觸發器,不影響運行結果;

5   Mysql觸發器經典案例
5.1   案例1 一條sql涉及多個表的update時,觸發得到update之前的舊值
【現象】表test_info上建有觸發器如下:
CREATE /*!50017 DEFINER = 'root'@'localhost' */ TRIGGER trig_test_info_update
AFTER UPDATE
ON FC_Word.test_info FOR EACH ROW
BEGIN
DECLARE tlevel INTEGER DEFAULT 0;
DECLARE ttype INTEGER DEFAULT 0;
SET tlevel = 4;
SET ttype = 33;
INSERT INTO TEST_Output.fcevent (te, le, uid, pid, uid, wid, bi, mbid, wl) SELECT ttype, tlevel, NEW.uid, NEW.pid, NEW.uid, NEW.wid, NEW.bi, NEW.mbid, wl FROM TEST_Word.wext2 where wid = NEW.wid;
/*。。。其余部分邏輯省略*/
END IF;
END;

        這個觸發器程序有點長,可以單看飄黃的兩句,即更新操作滿足第一個條件執行飄黃語句時,觸發器的行為。觸發器是建立在test_info表上的,飄黃語句中可以看到,也需要查詢wext2表。
執行如下sql1:

Update test_info a, wext2 b set a.th=(a.th+1), a.w4=(a.w4&8), b.wl=NULL where a.wid=b.wid and a.wid=142394379;

        可以看到sql中既修改了test_info2表,同時修改了wext2表,程序原意是觸發得到wext2表wl字段修改后的新值(即NULL);不過實驗得到,執行上述sql后,觸發器程序查詢到的wurl是sql修改之前的舊值。

再執行下面類似sql2:

Update wext2 a, test_info2 b set b.th=(b.th+1), b.w4=(b.w4&8), a.wl=NULL where a.wid=b.wid and a.wid=142394379;

        實驗的到,執行上述sql后,觸發器程序查詢到的wurl是sql修改之后的新值。

【原因】原因當然與sql中的別名a,b無關,而是和wext2表和test_info表的書寫順序有關。如本文3.4部分所述,一條sql涉及多個表的 update操作時,數據表字段、觸發器執行順序是mysql源碼包裝過的。在執行上述sql1時,先執行test_info的更新,然后是after觸發器,最后是wext2的更新,也就是說,在執行after觸發器時,wext2還沒有進行更新,所以觸發得到的是舊值。而執行sql2時,先執行 wext2更新,然后是test_info更新,最后是after觸發器,也就是說,在執行after觸發器時,wext2已經更新完畢,所以出去得到的是新值。
        引起上述現象是順序關系的,無論該表是否支持事務。在使用復雜的sql時,由於有些復雜的sql是mysql自己定義的,所以存在不確定性,存在風險,使用簡單的sql比較可控。

5.2   案例2 mysql5.0.19版本修改表結構后觸發器失效
【現象】userpref表上建有after類型觸發器,修改userpref表的外鍵關聯后,在userpref表中的新增記錄沒有觸發下來,即觸發器失效。
【原因】mysql5.0.19修改表結構是,觸發器消失。這是mysql5.0.19的一個bug,在創建觸發器時,會把觸發器的內容保存在 information_schema.TRIGGERS表中,同時在var目錄下創建觸發器的數據庫目錄下創建一個觸發器名稱為前綴,以TRN為后綴的文件,當修改觸發器的表時,information_schema.TRIGGERS表的內容會刪除,導致觸發器消失。

        在mysql5.0.45版本中,這個bug已經被修復。Mysql5.0.45版本的觸發器,無論是修改表的索引、外鍵,還是改變表字段,觸發器都不會失效。

5.3   案例3 刪除數據表后觸發器失效
【現象】聯調環境中存在dbA?dbB,主庫dbA上沒有觸發器,在從庫dbB上的FC_Word.wnegative表,FC_Word.wbuget 表上建有觸發器;觸發器開始運行正常,期間沒有對從庫的任何直接操作,有一日發現對wnegative表上的修改無法觸發。查看從庫狀態,同步正常;用 select TRIGGER_NAME from information_schema.TRIGGERS發現wnegative表上的觸發器消失了;在var/FC_Word目錄下也沒有 wnegative的.TRN文件,wnegative表上的觸發器不見了。

【分析】查找dbB的查詢日志,發現有一條:

100223 18:27:45 135939 Query       DROP TABLE IF EXISTS `wnegative`
135939 Query       CREATE TABLE `wnegative` (
KEY `Index_wnegative_planid` (`planid`),
KEY `Index_wnegative_unitid` (`unitid`)
135939 Query       /*!40000 ALTER TABLE `wnegative` DISABLE KEYS */
100223 18:27:46 135939 Query       INSERT INTO `wnegative` VALUES (614,1,289026,2911155,1848481);

        可以看到,在100223 18:27:45時,刪除了表wnegative,緊接着有創建表wnegative;查找觸發表發現,在100223 18:27:45時間后對wnegative的修改就沒有觸發了,而在這個之前對wnegative的修改是觸發正常的。故,懷疑對wnegative表的刪除使wnegative表上的觸發器也被刪除。對wnegative表的刪除是在主庫dbA上操作后,被同步到dbB上。

【原因】在刪除wnegative表時,mysql同時刪除了wegative表上的觸發器。
可以通過下面實驗證明上述猜測:
1)   首先在wnegative建立after insert型觸發器;
2)   增加一條wnegative中記錄;
3)   查看結果發現觸發器正確觸發;
4)   刪除wnegative表;
5)   使用select TRIGGER_NAME from information_schema.TRIGGERS查看所有觸發器,wnegative表上觸發器已經不存在了;同時到var/FC_Word目錄下,對應觸發器的.TRN文件也不存在了;
6)   重新創建wnegative表,並增加一條wnegative中記錄;沒有了wnegative表上觸發器,自然也不能觸發任何結果。

 

本文根據<mysql觸發器的實戰經驗>整理,內容主要來源於該文。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM