大大毛 的筆記

            DDM's Note

          哪怕沒(méi)有辦法一定有說(shuō)法,
          就算沒(méi)有鴿子一定有烏鴉,
          固執(zhí)無(wú)罪 夢(mèng)想有價(jià),
          讓他們驚訝.

          posts - 14, comments - 23, trackbacks - 0, articles - 58
             :: 首頁(yè) ::  :: 聯(lián)系 ::  :: 管理

          ADO提交多筆SQL的問(wèn)題

          Posted on 2009-02-17 18:50 大大毛 閱讀(471) 評(píng)論(0)  編輯  收藏 所屬分類: VB

          使用ADO時(shí)經(jīng)常都會(huì)遇到要利用事務(wù)批次提交SQL的情況,如果使用不當(dāng)?shù)奶峤环绞綍?huì)出現(xiàn)預(yù)料外的問(wèn)題,現(xiàn)在先看下面的示例代碼:

          ?1?Private?Sub?cmdRun_Click()
          ?2?On?Error?GoTo?ErrHandle
          ?3?????Dim?con?As?Connection
          ?4?????Dim?strSQL?As?String
          ?5?????strSQL?=?""
          ?6?????'第一筆SQL1
          ?7?????strSQL?=?strSQL?&?"Insert?Into?tb1?Values?(...)"?&?vbNewLine
          ?8?????'第二筆SQL2
          ?9?????strSQL?=?strSQL?&?"Update?tb1?Set?C=1?Where?..."?&?vbNewLine
          10?????'...
          11?????'第N筆SQLn
          12?????strSQL?=?strSQL?&?"Delete?tb1?Where?..."?&?vbNewLine
          13?????Set?con?=?getCon()??'獲取/打開(kāi)DB連線
          14?????'準(zhǔn)備事務(wù)
          15?????con.BeginTrans
          16?????'一批一起執(zhí)行
          17?????con.Execute?strSQL
          18?????'提交事務(wù)
          19?????con.CommitTrans
          20?ExitHandle:
          21?????If?con.State?=?1?Then?con.Close
          22?????Set?con?=?Nothing
          23?????Exit?Function
          24?ErrHandle:
          25?????con.RollbackTrans
          26?????GoTo?ExitHandle
          27?????MsgBox?Err.Description
          28?End?Sub

          ???上面這段程式利用換行符(分號(hào)也可)來(lái)將多條SQL合成一個(gè)字符串,最後在事務(wù)中執(zhí)行一次就OK,既簡(jiǎn)潔又漂亮的想法。
          ???看似OK,但實(shí)際卻是埋下了禍端。從事務(wù)的機(jī)制來(lái)看,在事務(wù)中提交的SQL應(yīng)該是一起成功/失敗的,而且這裏也有利用異常捕獲機(jī)制來(lái)實(shí)現(xiàn)RollBack,那麼在使用時(shí)到底是會(huì)出現(xiàn)什麼情況呢?
          ???(0) SQL1,SQL2,...SQLn其中有語(yǔ)句含有非執(zhí)行時(shí)的語(yǔ)法錯(cuò)誤,比如說(shuō)嵌套語(yǔ)句少掉一個(gè)右括號(hào)等;
          ??????OK。這種情況下,可以發(fā)現(xiàn)執(zhí)行結(jié)果如預(yù)期,SQL1 -> SQLn都不會(huì)被執(zhí)行,且會(huì)提示錯(cuò)誤訊息。
          ???(1) SQL1,SQL2,...SQLn都執(zhí)行成功;
          ??????OK。這種情況下,可以發(fā)現(xiàn)執(zhí)行結(jié)果如預(yù)期,SQL1 -> SQLn都會(huì)被執(zhí)行,可以正確提交事務(wù)。
          ???(2) SQL1,SQL2,...SQLn其中有語(yǔ)句會(huì)執(zhí)行失敗;
          ??????(2.1) SQL1可以執(zhí)行,而SQL2會(huì)發(fā)生執(zhí)行時(shí)期錯(cuò)誤(比如UPDATE上去欄位超過(guò)寬度);
          ?????????NO。Execute執(zhí)行成功,查詢結(jié)果會(huì)發(fā)現(xiàn)SQL1的結(jié)果有提交,而SQL2以及之後的SQL都沒(méi)有執(zhí)行。
          ??????(2.2) SQL1會(huì)發(fā)生執(zhí)行時(shí)期錯(cuò)誤(比如UPDATE上去欄位超過(guò)寬度),而SQL2及其後的SQL可以被執(zhí)行;
          ?????????OK。這種情況下,可以發(fā)現(xiàn)有提示錯(cuò)誤訊息,事務(wù)會(huì)被RollBack,SQL1 -> SQLn都不會(huì)被執(zhí)行。

          ???通過(guò)上面的幾種情況可以得到結(jié)論,如果是以一整個(gè)字串(中間用換行或分號(hào)分隔)來(lái)提交多筆SQL命令時(shí),在所有SQL語(yǔ)法檢查OK後,執(zhí)行的成功與否取決於第1筆SQL的執(zhí)行狀態(tài),因此就是說(shuō)如果第一筆SQL執(zhí)行OK,那麼該事務(wù)就一定會(huì)被Commit

          ???所以說(shuō),在使用事務(wù)提交多筆SQL時(shí)不能使用上面的提交方式,而必須逐筆的提交才行。


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          i am ddm

          主站蜘蛛池模板: 南安市| 双流县| 乌苏市| 安泽县| 临朐县| 怀仁县| 甘谷县| 松滋市| 尉氏县| 从江县| 民勤县| 务川| 伊春市| 金山区| 阳城县| 阿图什市| 沈阳市| 桐乡市| 达尔| 太仓市| 博客| 西盟| 汤阴县| 闸北区| 蒲城县| 小金县| 肇州县| 南岸区| 印江| 睢宁县| 贞丰县| 军事| 建平县| 太和县| 大新县| 定边县| 策勒县| 绥中县| 太仓市| 稷山县| 彭泽县|