《Mysql應(yīng)用MySQL SELECT同時(shí)UPDATE同一張表問(wèn)題發(fā)生及解決》要點(diǎn):
本文介紹了Mysql應(yīng)用MySQL SELECT同時(shí)UPDATE同一張表問(wèn)題發(fā)生及解決,希望對(duì)您有用。如果有疑問(wèn),可以聯(lián)系我們。
MySQL不允許SELECT FROM后面指向用作UPDATE的表,有時(shí)候讓人糾結(jié).當(dāng)然,有比創(chuàng)建無(wú)休止的臨時(shí)表更好的辦法.本文解釋如何UPDATE一張表,同時(shí)在查詢(xún)子句中使用SELECT.
問(wèn)題描述 假設(shè)我要UPDATE的表跟查詢(xún)子句是同一張表,這樣做有許多種原因,例如用統(tǒng)計(jì)數(shù)據(jù)更新表的字段(此時(shí)需要用group子句返回統(tǒng)計(jì)值),從某一條記錄的字段update另一條記錄,而不必使用非標(biāo)準(zhǔn)的語(yǔ)句,等等.舉個(gè)例子:
代碼如下:
create table apples(variety char(10) primary key, price int);
insert into apples values('fuji', 5), ('gala', 6);
update apples
set price = (select price from apples where variety = 'gala')
where variety = 'fuji';
錯(cuò)誤提示是:ERROR 1093 (HY000): You can't specify target table 'apples' for update in FROM clause. MySQL手冊(cè)UPDATE documentation這下面有說(shuō)明 : “Currently, you cannot update a table and select from the same table in a subquery.”
在這個(gè)例子中,要解決問(wèn)題也十分簡(jiǎn)單,但有時(shí)候不得不通過(guò)查詢(xún)子句來(lái)update目標(biāo).好在我們有辦法.
解決辦法 既然MySQL是通過(guò)臨時(shí)表來(lái)實(shí)現(xiàn)FROM子句里面的嵌套查詢(xún),那么把嵌套查詢(xún)裝進(jìn)另外一個(gè)嵌套查詢(xún)里,可使FROM子句查詢(xún)和保存都是在臨時(shí)表里進(jìn)行,然后間接地在外圍查詢(xún)被引用.下面的語(yǔ)句是正確的:
代碼如下:
update apples
set price = (
select price from (
select * from apples
) as x
where variety = 'gala')
where variety = 'fuji';
如果你想了解更多其中的機(jī)制,請(qǐng)閱讀MySQL Internals Manual相關(guān)章節(jié).
沒(méi)有解決的問(wèn)題 一個(gè)常見(jiàn)的問(wèn)題是,IN()子句優(yōu)化廢品,被重寫(xiě)成相關(guān)的嵌套查詢(xún),有時(shí)(往往?)造成性能低下.把嵌套查詢(xún)裝進(jìn)另外一個(gè)嵌套查詢(xún)里并不能阻止它重寫(xiě)成相關(guān)嵌套,除非我下狠招.這種情況下,最好用JOIN重構(gòu)查詢(xún)(rewrite such a query as a join).
另一個(gè)沒(méi)解決的問(wèn)題是臨時(shí)表被引用多次.“裝進(jìn)嵌套查詢(xún)”的技巧無(wú)法解決這些問(wèn)題,因?yàn)樗鼈冊(cè)诰幾g時(shí)被創(chuàng)建,而上面討論的update問(wèn)題是在運(yùn)行時(shí).
轉(zhuǎn)載請(qǐng)注明本頁(yè)網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/4019.html