無法執行的update問題解析
今天有個同事向我反饋一個問題,說是客戶在部署他們提供的一個sql語句時,報了ora錯誤,想讓我幫忙看看是什麼原因。
update sub_errs set error_status = 'READY_TO_RECYCLE' WHERE sub_appl_id = 3008 AND ENTITY_ID = 8336079 AND MASTER_TRX_ID = 202809364 and error_status = 'PENDING_DEPENDENCY'
Error report -
SQL Error: ORA-02290: ????????????????????????????? (APPO.SUB_ERRS_1CK)
首先看錯誤,還真接上小語種了,自己百度翻譯了下,是違反約束條件的意思,也是開個玩笑,這個問題可以透過oerr來檢視oracle的解釋。
02290, 00000, "check constraint (%s.%s) violated"
// *Cause: The values being inserted do not satisfy the named check
// constraint.
// *Action: do not insert values that violate the constraint.
可以看出應該是約束的地方出問題了,從約束的命名來看是以CK結尾,即check constraint。
檢視user_constraints中的search_condition欄位,條件著實複雜,search_condition的條件如下:
(depen_ind='S' AND error_status='PENDING_DEPENDENCY')
OR (depen_ind='S' AND error_status='COMPLETED')
OR (depen_ind='S' AND error_status='PURGED')
OR depen_ind='B'
OR depen_ind='N'
即對於指定的欄位error_status 需要滿足上面的這些條件。這個check constraint算是一個比較複雜的約束了。
可能有些人看這個約束就有點暈,到底是希望滿足條件還是不滿足條件啊。
我們可以類比一下,如果是not null constraint,可能約束就是類似 xxxx is not null的形式,這個時候是希望這個欄位不為空的,即滿足條件。所以這個問題是希望對error_status ,滿足上面的條件才行。
給同事解釋了一通,讓他去看看是不是現有環境中存在資料問題,是不是因為資料問題導致條件不滿足的。
結果過了一會同事又過來向我確認,說按照那個條件查出的結果和原有的一致的。都是19條資料。
因為表中的資料很多,所以為了儘快復現這個問題,自己採用了exp的query選項匯出資料,這樣就會只匯出19條資料,資料量就小多了,匯入到一個測試環境中,就可以大膽的測試了。
exp xxxxx/xxx file=a.dmp tables=sub_errs query=\" where sub_appl_id = 3008 AND ENTITY_ID = 8336079 \"
我先根據id來抽取資料,抽取出19條資料來,然後在測試使用者中使用對應的約束進行修改,看看問題是否會復現。
匯入資料很順利,19條資料很快就匯入了。
imp xxxxx/xxxx file=a.dmp tables=sub_errs indexes=n grants=n ignore=Y constraints=n buffer=9102000
這個時候嘗試重現,發現問題依舊。
這個時候我們把問題拆分一下,先把update改寫成為select語句。資料條數是19條。
select count(*) from sub_errs WHERE sub_appl_id = 3008 AND ENTITY_ID = 8336079 AND MASTER_TRX_ID = 202809364 and error_status = 'PENDING_DEPENDENCY'
and
((depen_ind='S' AND error_status='PENDING_DEPENDENCY')
OR (depen_ind='S' AND error_status='COMPLETED')
OR (depen_ind='S' AND error_status='PURGED')
OR depen_ind='B'
OR depen_ind='N')
這個時候其實約束的驗證條件進行校驗 error_status和depen_ind這兩個欄位,因為現有的資料中depen_ind已經是S了,所以資料上沒有問題。
然後我們進一步分析。update會把error_status修改為'READY_TO_RECYCLE',這個時候細看過濾條件中,是沒有符合的error_status校驗的,這個時候depen_ind還是S,就會出問題,
因為這個時候從depen_ind+error_status還是單純考慮depen_ind都是有問題的,和驗證條件是有衝突的。
這個時候因為error_status是READY_TO_RECYCLE',所以第1,2兩個條件不會起作用,考慮第3,4個條件,就會發現沒有匹配的情況。難怪會拋錯。
((depen_ind='S' AND error_status='PENDING_DEPENDENCY')
OR (depen_ind='S' AND error_status='COMPLETED')
OR (depen_ind='S' AND error_status='PURGED')
OR depen_ind='B'
OR depen_ind='N')
明白了這點之後,就提醒同事,指令碼應該存在問題,也修改同時修改depen_ind欄位的值,需要修改為B或者N,這個由他們來做進一步的確認了。
最後修改後的語句為:
update sub_errs set error_status = 'READY_TO_RECYCLE',depen_ind='N' WHERE sub_appl_id = 3008 AND ENTITY_ID = 8336079 AND MASTER_TRX_ID = 202809364 and error_status = 'PENDING_DEPENDENCY'
這個問題的解決就告一段落了。
這個案例帶給我的啟示就是看似是約束導致的問題,一般運維人員可能會直接認為是資料問題把問題直接退給開發人員,其實從開發人員的角度來說,去進一步排查這個問題就會顯得很困難,不知道該從何開始。
其實問題最後的原因就是語句的修改不夠規範和全面導致約束的校驗失敗,發現這個問題的過程還是需要一些耐心的。
update sub_errs set error_status = 'READY_TO_RECYCLE' WHERE sub_appl_id = 3008 AND ENTITY_ID = 8336079 AND MASTER_TRX_ID = 202809364 and error_status = 'PENDING_DEPENDENCY'
Error report -
SQL Error: ORA-02290: ????????????????????????????? (APPO.SUB_ERRS_1CK)
首先看錯誤,還真接上小語種了,自己百度翻譯了下,是違反約束條件的意思,也是開個玩笑,這個問題可以透過oerr來檢視oracle的解釋。
02290, 00000, "check constraint (%s.%s) violated"
// *Cause: The values being inserted do not satisfy the named check
// constraint.
// *Action: do not insert values that violate the constraint.
檢視user_constraints中的search_condition欄位,條件著實複雜,search_condition的條件如下:
(depen_ind='S' AND error_status='PENDING_DEPENDENCY')
OR (depen_ind='S' AND error_status='COMPLETED')
OR (depen_ind='S' AND error_status='PURGED')
OR depen_ind='B'
OR depen_ind='N'
即對於指定的欄位error_status 需要滿足上面的這些條件。這個check constraint算是一個比較複雜的約束了。
可能有些人看這個約束就有點暈,到底是希望滿足條件還是不滿足條件啊。
我們可以類比一下,如果是not null constraint,可能約束就是類似 xxxx is not null的形式,這個時候是希望這個欄位不為空的,即滿足條件。所以這個問題是希望對error_status ,滿足上面的條件才行。
給同事解釋了一通,讓他去看看是不是現有環境中存在資料問題,是不是因為資料問題導致條件不滿足的。
結果過了一會同事又過來向我確認,說按照那個條件查出的結果和原有的一致的。都是19條資料。
因為表中的資料很多,所以為了儘快復現這個問題,自己採用了exp的query選項匯出資料,這樣就會只匯出19條資料,資料量就小多了,匯入到一個測試環境中,就可以大膽的測試了。
exp xxxxx/xxx file=a.dmp tables=sub_errs query=\" where sub_appl_id = 3008 AND ENTITY_ID = 8336079 \"
匯入資料很順利,19條資料很快就匯入了。
imp xxxxx/xxxx file=a.dmp tables=sub_errs indexes=n grants=n ignore=Y constraints=n buffer=9102000
這個時候嘗試重現,發現問題依舊。
這個時候我們把問題拆分一下,先把update改寫成為select語句。資料條數是19條。
select count(*) from sub_errs WHERE sub_appl_id = 3008 AND ENTITY_ID = 8336079 AND MASTER_TRX_ID = 202809364 and error_status = 'PENDING_DEPENDENCY'
and
((depen_ind='S' AND error_status='PENDING_DEPENDENCY')
OR (depen_ind='S' AND error_status='COMPLETED')
OR (depen_ind='S' AND error_status='PURGED')
OR depen_ind='B'
OR depen_ind='N')
這個時候其實約束的驗證條件進行校驗 error_status和depen_ind這兩個欄位,因為現有的資料中depen_ind已經是S了,所以資料上沒有問題。
然後我們進一步分析。update會把error_status修改為'READY_TO_RECYCLE',這個時候細看過濾條件中,是沒有符合的error_status校驗的,這個時候depen_ind還是S,就會出問題,
因為這個時候從depen_ind+error_status還是單純考慮depen_ind都是有問題的,和驗證條件是有衝突的。
這個時候因為error_status是READY_TO_RECYCLE',所以第1,2兩個條件不會起作用,考慮第3,4個條件,就會發現沒有匹配的情況。難怪會拋錯。
((depen_ind='S' AND error_status='PENDING_DEPENDENCY')
OR (depen_ind='S' AND error_status='COMPLETED')
OR (depen_ind='S' AND error_status='PURGED')
OR depen_ind='B'
OR depen_ind='N')
明白了這點之後,就提醒同事,指令碼應該存在問題,也修改同時修改depen_ind欄位的值,需要修改為B或者N,這個由他們來做進一步的確認了。
最後修改後的語句為:
update sub_errs set error_status = 'READY_TO_RECYCLE',depen_ind='N' WHERE sub_appl_id = 3008 AND ENTITY_ID = 8336079 AND MASTER_TRX_ID = 202809364 and error_status = 'PENDING_DEPENDENCY'
這個問題的解決就告一段落了。
這個案例帶給我的啟示就是看似是約束導致的問題,一般運維人員可能會直接認為是資料問題把問題直接退給開發人員,其實從開發人員的角度來說,去進一步排查這個問題就會顯得很困難,不知道該從何開始。
其實問題最後的原因就是語句的修改不夠規範和全面導致約束的校驗失敗,發現這個問題的過程還是需要一些耐心的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-1686924/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Linux無法解析主機問題Linux
- ASP.NET Core 2.0 整合測試無法執行的問題ASP.NET
- 執行spoon.bat時Kettle無法啟動問題解決BAT
- VIPCA無法執行PCA
- 執行npm update等命令出錯後如何分析問題根源NPM
- SVN命令解析以及問題解決(update...)
- 解決 sublime text3 執行python檔案無法input的問題Python
- 一個執行計劃解析的小問題分析
- dubbo註冊中心佔位符無法解析問題
- 資料庫無法update資料庫
- Excel無法做到的問題Excel
- 多執行緒 HashMap 死迴圈 問題解析執行緒HashMap
- dubbo註冊中心佔位符無法解析問題(二)
- Ubuntu無法解析域名DNS指向127.0.0.53問題處理UbuntuDNS
- JSF的outputText時,無法處理換行問題JS
- update的機制問題
- Java在Linux環境下執行MySQL命令無法獲取結果的問題JavaLinuxMySql
- eos docker執行後無法執行cleosDocker
- ORA-01775無法檢視SQL執行計劃的問題的解決方案SQL
- 索引無法消除排序的問題索引排序
- 執行JPetStore的問題
- crontab的執行問題
- 解決Snackbar無法進行跨頁面展示的問題
- Linux 作業系統指令碼格式問題導致指令碼無法執行Linux作業系統指令碼
- 搞定“無線無法上網,診斷策略服務未執行”的問題了,最終解決方案如下
- 解決無法使用VI的問題
- Windows Defender無法開啟的問題Windows
- docker 中vim 命令 無法執行Docker
- 物化檢視job無法執行
- ZeroMQ 3.2.2 XP下無法執行MQ
- FORALL執行UPDATE語句
- JDk1.7 HashMap原始碼解析——執行緒安全問題JDKHashMap原始碼執行緒
- 執行緒問題執行緒
- java多執行緒執行問題Java執行緒
- 簡單幾步解決gbt_setup在win10中無法執行的問題Win10
- crontab無法執行perl指令碼 手工卻成功執行指令碼
- Web應用部署在WebLogic中Basic認證無法執行問題及解決Web
- [轉]一次linux下的crontab中定義的任務計劃無法執行的問題。Linux