關(guān)于Oracle游標(biāo)的一些項(xiàng)目中遇到的邏輯問題
今天 在項(xiàng)目中看一個(gè)存儲(chǔ)過程的時(shí)候,發(fā)現(xiàn)同事寫的之前的有些邏輯錯(cuò)誤,可能這個(gè)錯(cuò)誤比較典型吧 拿出來分享一下,不使用公司的數(shù)據(jù)庫,所以在自己的機(jī)子上模擬了一下這個(gè)場(chǎng)景。OK
首先,就是2個(gè)表,
表temp1,包括id1,val1,2個(gè)字段,
表temp2,包括id2,val2 2個(gè)字段。
首先,情景大致是這樣的,2個(gè)表的ID是有關(guān)聯(lián)的,就是把temp2中包含的temp1的id的數(shù)據(jù),在temp1中把val1都設(shè)置為1,不包含的設(shè)置為0.
首先,發(fā)一下之前錯(cuò)誤的存儲(chǔ)過程。
create or replace procedure mysdtest as cursor te_v1 is select id1,val1 from Temp1; cursor te_v2 is select id2,val2 from Temp2; v1_t te_v1%rowtype; v2_t te_v2%rowtype; begin open te_v1; loop fetch te_v1 into v1_t; exit when te_v1%notfound; open te_v2; loop fetch te_v2 into v2_t; exit when te_v2%notfound; if v1_t.id1=v2_t.id2 then update temp1 set val1='1' where id1=v1_t.id1; else update temp1 set val1='0' where id1=v1_t.id1; end if; end loop; close te_v2; end loop; close te_v1; end; |
這樣寫邏輯是存在問題的,2層循環(huán),結(jié)果就會(huì)發(fā)現(xiàn)都是0,仔細(xì)讀一下程序就會(huì)發(fā)現(xiàn)問題
比如說有一個(gè)值 t1 在表temp1中有值,應(yīng)該更新val1為1,但是遍歷到下一個(gè)t2時(shí),此時(shí)t1不符合,然后就執(zhí)行else 那么t1的val1就又變回了0,所以,程序執(zhí)行完,都執(zhí)行了else里面的,當(dāng)然就錯(cuò)了。
正確的寫法很多種,這里我就以設(shè)置帶參數(shù)的游標(biāo)為例,將2個(gè)游標(biāo)建立關(guān)系,再進(jìn)行遍歷就不會(huì)出現(xiàn)問題。
如下:
create or replace procedure myt as cursor te_v1 is select id1,val1 from Temp1; cursor te_v2(idv2 varchar2) is select count(*) from temp2 where id2=idv2; v1_t te_v1%rowtype; numv varchar2(2); begin open te_v1; loop fetch te_v1 into v1_t; exit when te_v1%notfound; open te_v2(v1_t.id1); fetch te_v2 into numv; if numv=0 then update TEMP1 set val1='0' where id1=v1_t.id1; else update TEMP1 set val1='1' where id1=v1_t.id1; end if; close te_v2; end loop; close te_v1; end; |
ok,這種問題我們應(yīng)該注意到
posted on 2014-06-25 15:55 順其自然EVO 閱讀(135) 評(píng)論(0) 編輯 收藏 所屬分類: 測(cè)試學(xué)習(xí)專欄