標籤:log mysql 分隔字元 myisam 對象 tip excel匯入 欄位 分享圖片
2018年8月15日,今天由於之前的失誤(因為剛來公司不太懂業務導致的)使一個不應該賦值的欄位給賦值了,神奇的是居然上生產了,後來就是一系列資料錯誤,為了及時抑制事態的嚴重,只能寫觸發器了,因為改代碼已經不現實了,大致情況是這樣的,有一張表裡面一個訂單號和一個訂單狀態,由於當時是excel匯入的資料,excel並沒有這兩個欄位,當時來的時間不長,看到這個表有個訂單號,感覺一個是個重要的欄位,就問了一組長,他說用UUID賦值就行,後來就賦值了,賦值以後會不斷的調取華泰那邊的介面,因為這個訂單號是我們產生的,華泰並沒有,然後就是各種錯,後來組長說誰讓你賦值的,你見過那個業務欄位可以隨機賦值的,心裡一萬個MMP,當時不是你說的嗎,後來就洗個觸發器止損吧!!!
原文地址轉載:https://www.cnblogs.com/phpper/p/7587031.html 通過這問大神的指點才寫出來
先上我寫的觸發器:
DROP TRIGGER if EXISTS upd_che;
CREATE TRIGGER upd_che BEFORE INSERT ON wl_ser_info FOR EACH ROW
BEGIN
IF (
NEW.SERVICE_ORDER_STATUS = ‘‘
OR NEW.SERVICE_ORDER_STATUS IS NULL
) THEN
SET NEW.SERVICE_ORDERNO = NULL;
end if;
END;
MySQL好像從5.0.2版本就開始支援觸發器的功能了,本次部落格就來介紹一下觸發器,首先還是談下概念性的東西吧:
什麼是觸發器
觸發器是與表有關的資料庫物件,在滿足定義條件時觸發,並執行觸發器中定義的語句集合。觸發器的這種特性可以協助應用在資料庫端確保資料的完整性。
建立觸發器:
CREATE TRIGGER trigger_name trigger_time trigger_event ON tb_name FOR EACH ROW trigger_stmttrigger_name:觸發器的名稱tirgger_time:觸發時機,為BEFORE或者AFTERtrigger_event:觸發事件,為INSERT、DELETE或者UPDATEtb_name:表示建立觸發器的表明,就是在哪張表上建立觸發器trigger_stmt:觸發器的程式體,可以是一條SQL語句或者是用BEGIN和END包含的多條語句所以可以說MySQL建立以下六種觸發器:BEFORE INSERT,BEFORE DELETE,BEFORE UPDATEAFTER INSERT,AFTER DELETE,AFTER UPDATE
其中,觸發器名參數指要建立的觸發器的名字
BEFORE和AFTER參數指定了觸發執行的時間,在事件之前或是之後
FOR EACH ROW表示任何一條記錄上的操作滿足觸發事件都會觸發該觸發器
建立有多個執行語句的觸發器
CREATE TRIGGER 觸發器名 BEFORE|AFTER 觸發事件ON 表名 FOR EACH ROWBEGIN 執行語句列表END
其中,BEGIN與END之間的執行語句列表參數表示需要執行的多個語句,不同語句用分號隔開
tips:一般情況下,mysql預設是以 ; 作為結束執行語句,與觸發器中需要的分行起衝突
為解決此問題可用DELIMITER,如:DELIMITER ||,可以將結束符號變成||
當觸發器建立完成後,可以用DELIMITER ;來將結束符號變成;
mysql> DELIMITER ||
mysql> CREATE TRIGGER demo BEFORE DELETE
-> ON users FOR EACH ROW
-> BEGIN
-> INSERT INTO logs VALUES(NOW());
-> INSERT INTO logs VALUES(NOW());
-> END
-> ||
Query OK, 0 rows affected (0.06 sec)
mysql> DELIMITER ;
上面的語句中,開頭將結束符號定義為||,中間定義一個觸發器,一旦有滿足條件的刪除操作
就會執行BEGIN和END中的語句,接著使用||結束
最後使用DELIMITER ; 將結束符號還原
tigger_event:
load data語句是將檔案的內容插入到表中,相當於是insert語句,而replace語句在一般的情況下和insert差不多,但是如果表中存在primary 或者unique索引的時候,如果插入的資料和原來的primary key或者unique相同的時候,會刪除原來的資料,然後增加一條新的資料,所以有的時候執行一條replace語句相當於執行了一條delete和insert語句。
觸發器可以是一條SQL語句,也可以是多條SQL代碼塊,那如何建立呢?
DELIMITER $ #將語句的分隔字元改為$BEGINsql1;sql2;...sqlnEND $DELIMITER ; #將語句的分隔字元改回原來的分號";"
在BEGIN...END語句中也可以定義變數,但是只能在BEGIN...END內部使用:
DECLARE var_name var_type [DEFAULT value] #定義變數,可指定預設值SET var_name = value #給變數賦值
NEW和OLD的使用:
根據以上的表格,可以使用一下格式來使用相應的資料:
NEW.columnname:新增行的某列資料OLD.columnname:刪除行的某列資料
說了這麼多現在我們來建立一個觸發器吧!
現在有表如下:
使用者users表
CREATE TABLE `users` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL, `add_time` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `name` (`name`(250)) USING BTREE) ENGINE=MyISAM AUTO_INCREMENT=1000001 DEFAULT CHARSET=latin1;
日誌logs表:
CREATE TABLE `logs` ( `Id` int(11) NOT NULL AUTO_INCREMENT, `log` varchar(255) DEFAULT NULL COMMENT ‘日誌說明‘, PRIMARY KEY (`Id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘日誌表‘;
需求是:當在users中插入一條資料,就會在logs中產生一條日誌資訊。
建立觸發器:
DELIMITER $CREATE TRIGGER user_log AFTER INSERT ON users FOR EACH ROWBEGINDECLARE s1 VARCHAR(40)character set utf8;DECLARE s2 VARCHAR(20) character set utf8;#後面發現中文字元編碼出現亂碼,這裡設定字元集SET s2 = " is created";SET s1 = CONCAT(NEW.name,s2); #函數CONCAT可以將字串串連INSERT INTO logs(log) values(s1);END $DELIMITER ;
查看觸發器SHOW TRIGGERS語句查看觸發器資訊
Tip:
上面我用的navicat直接建立,如果大家用的mysql front,name這裡會有個區別,我們刪除剛才的觸發器,在Mysql front中測試
drop trigger user_log;#刪除觸發器
開啟Mysql Front:
mysql front在編譯sql時,不用定義結尾分隔字元,修改後的sql直接這樣既可:
#DELIMITER $CREATE TRIGGER user_log AFTER INSERT ON users FOR EACH ROWBEGINDECLARE s1 VARCHAR(40)character set utf8;DECLARE s2 VARCHAR(20) character set utf8;SET s2 = " is created";SET s1 = CONCAT(NEW.name,s2); #函數CONCAT可以將字串串連INSERT INTO logs(log) values(s1);END #$#DELIMITER ;
這裡再囉嗦幾句:
tips:SHOW TRIGGERS語句無法查詢指定的觸發器
在triggers表中查看觸發器資訊
SELECT * FROM information_schema.triggers;
結果顯示了所有觸發器的詳細資料,同時,該方法可以查詢制定觸發器的詳細資料
SELECT * FROM information_schema.triggers WHERE TRIGGER_NAME=‘user_log‘;
tips:所有觸發器資訊都儲存在information_schema資料庫下的triggers表中
可以使用SELECT語句查詢,如果觸發器資訊過多,最好通過TRIGGER_NAME欄位指定查詢
回到上面,我們建立好了觸發器,繼續在users中插入資料並查看資料:
insert into users(name,add_time) values(‘周伯通‘,now());
mysql觸發器trigger