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