[数据库] Navicat for MySQL换种思维解决插入同时更新数据
? ? ? ? 這篇文章是我的學生在實際項目中遇到的一個案例,在對某張表插入數據過程中,某些特定的字段需也要進行更新,比如說部門編號在前端插入,而部門名稱在插入時應該自動更新,如果前端設置選擇編號又選擇部門就重復功能了,那么數據庫怎么實現呢?
? ? ? ? 最早學生想通過觸發器實現,設置一個插入觸發器,插入的同時更新數據,但是問題來了,在同一張表中,觸發器是不能同時插入又更新的。這篇文章主要討論這個問題的解決方法。同時為了加深大家對觸發器的映像,也會在給大家講述些觸發器的知識,起到討論的作用。
? ? ? ? 希望文章對你有所幫助,尤其是我的學生和數據庫基礎的博友以及解決實際項目中的類似問題。如果文章中存在錯誤或不足之處,還請海涵~
? ? ? ? 推薦前文:
? ? ? ??[數據庫] Navicat for MySQL觸發器更新和插入操作
? ? ? ??[數據庫] Navicat for MySQL事件Event實現數據每日定期操作
一. 觸發器問題
? ? ? ? 現在存在兩張表。第一張表為部門表department,核心字段為unit(學院名稱)、depid(學院編號),如下圖所示:
? ? ? ? 第二張表為插入信息表task,depid表示部門編號、source表示部門名稱,對應表department表的unit字段。還有插入時間、公告事件等字段,這里省略了。
? ? ? ? 現在前端有個按鈕,選擇部門編號,但是想通過department部門表同時插入部門名稱,怎么實現呢?首先,學生想到的是通過觸發器,如下所示:
DROP TRIGGER IF EXISTS `upd_info`; create trigger upd_info after insert on task for each row begin update task,department set source = department.unit where task.depid=department.depid; end; ? ? ? ? 觸發器設置成功。但是當插入數據時,報錯如下所示:[Err] 1442 - Can't update table 'task' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
? ? ? ? 注意:該錯誤表示如果你在觸發器里面對剛剛插入的數據進行了 insert/update, 則出現這個問題。因為會造成循環的調用。解決方法通過set設置值。
? ? ? ? 參考地址:http://blog.csdn.net/java2000_net/article/details/3857579
二. 觸發器解決
? ? ? ? 現在修改需要通過set來設置值,我修改如下所示:
DROP TRIGGER IF EXISTS `test`; create trigger test before insert on task for each row begin declare dname varchar(20);select department.unit into dname from department,task where task.depid=department.depid and task.depid=new.depid;set new.source = dname; end; ? ? ? ? 其中需要注意幾點:
? ? ? ? 1.觸發器Before和After的區別。
? ? ? ? (1) before(insert、update)可以對new進行修改;
? ? ? ? (2) after不能對new進行修改;
? ? ? ? (3) 兩者都不能修改old數據;
? ? ? ? (4) 對于Insert語句,只有new是合法的,對于delete語句,只有old合法,而update可以在new和old同時使用。
? ? ? ? 否則,在after insert觸發器中使用old,報錯如下:
? ? ? ? [Err] 1363 - There is no OLD row in on INSERT trigger
? ? ? ? 2.這里使用declare定義變量,并且select a into b把查詢結果a賦值到b使用。
? ? ? ? 但是運行結果是沒有反應,因為查詢條件中task.depid=new.depid在before insert觸發器中,插入數據前進行查詢,其結果是空的;而使用task.depid=old.depid又不能在insert中使用old。
? ? ? ? 比如執行下列SQL語句:
insert task (depid) VALUES('1067105002'); ? ? ? ? 輸出結果如下所示:
? ? ? ? 那怎么解決呢?解決方法包括:
? ? ? ? 1.后臺執行插入語句后,再執行一條Update語句,更新該字段是最方便的操作;
? ? ? ? 2.通過Event實時更新單位名稱,參考前文:
? ? ? ??[數據庫] Navicat for MySQL事件Event實現數據每日定期操作
? ? ? ? 但是如果需要通過SQL語句實現呢?那么我想到的是在使用insert插入過程中調用select查詢,這就是我說的換個思維解決該問題。
三. 換個思維解決
? ? ? ? SQL語句代碼如下:
INSERT INTO task(depid,source) SELECT depid, unit FROM department where department.depid='1067103002'; ? ? ? ? 運行結果如下所示,可以看到插入數據成功,其中taskid是自增整型,單位名稱添加成功了。后臺把'1067103002'換成對應的Java變量即可連接前端插入。
? ? ? ? 同樣,有些時候需要插入條件判斷,如果不存在則插入替代設置唯一性,代碼為:
? ? ? ??語法:MySQL中INSERT INTO SELECT的使用 -?RoadGY
? ? ? ??MySQL INSERT插入條件判斷:如果不存在則插入
? ? ? ? 同時,強烈推薦大家閱讀"老紫竹"老師的數據庫博客,參考:
? ? ? ? http://blog.csdn.net/java2000_net/article/details/4533826
? ? ? ? 最后希望在線筆記對您有所幫助,基礎性文章,如果存在錯誤或不足之處,還請海涵~還是娜么開心、娜么美麗。
? ? ? ?(By:Eastmount 2017-03-12 晚上1點???http://blog.csdn.net//eastmount/?)
總結
以上是生活随笔為你收集整理的[数据库] Navicat for MySQL换种思维解决插入同时更新数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [数据库] Navicat for My
- 下一篇: [python爬虫] Selenium爬