天天看點

從一條sql報錯解決過程學習程式員查bug的思路

從oracle遷移資料到達夢後,發現資料庫預設值都丢失了。于是我想從oracle資料庫将預設值查出來,在達夢資料庫加回去。

于是上網查了一下,看怎麼擷取oracle資料庫字段預設值資訊,找到了這個sql。

select t.column, t.data_type, t.data_length, t.nullable, t.data_default from USER_TAB_COLS t where TABLE_NAME = 'AA'

但把sql拿到資料庫跑時卻發現有問題,報了一個錯:

從一條sql報錯解決過程學習程式員查bug的思路

粗略掃了一下報錯資訊,沒看懂錯在哪裡。這跟我們平時碰上程式bug,但日志不清晰,看問題在哪是一樣的。
看了一下sql,主要有三部分,select,from語句(user_tab_cols是一個視圖),還有where條件,錯誤可能是select部分,或者user_tab_cols視圖語句或者是where條件語句造成的,但不知道是哪一部分出錯。
           

于是我先嘗試把where條件去掉,看還會不會報錯。

從一條sql報錯解決過程學習程式員查bug的思路
結果還是一樣的錯,那說明錯誤位置應該不在where條件裡面,那繼續嘗試縮小範圍。
           

這次我一步到位,把sql簡化成隻有一個元素:表名

從一條sql報錯解決過程學習程式員查bug的思路
發現可以查詢成功,那應該在select語句裡面。 看查詢有多個字段,暫時不知道是哪個字段有問題,嘗試删除後面一半。
           
從一條sql報錯解決過程學習程式員查bug的思路
這時發現問題還在,那應該是前面兩個字段有問題。繼續删除一個字段再試。
           
從一條sql報錯解決過程學習程式員查bug的思路
這時還是報錯,但錯誤範圍已經很小了。熟悉oracle的人一看就應該能知道column是關鍵字,這裡應該是字段名寫錯了。(後來發現正确字段名應該是column_name)
如果這時還想不起來錯誤原因怎麼辦?——繼續删減。看我下面的操作,删除别名t
           
從一條sql報錯解決過程學習程式員查bug的思路
删除到這裡,發現還是報錯,但錯誤提示不一樣了。這時再上網查一下,關于oracle的column資訊,會在百度發現很多相關内容。這時有一定程式設計經驗的人應該肯定能回憶起來。
           
從一條sql報錯解決過程學習程式員查bug的思路

發現問題後,修改好,現在可以正常查出預設值了。

從一條sql報錯解決過程學習程式員查bug的思路
這裡展示了一種程式員查bug的思路,就是不斷減少可能導緻報錯的内容,直到錯誤不複現(或者錯誤發生變化),問題足夠簡單,可以一眼了然知道原因。
           

通過減少變量,逐漸增加确定性,這是一種程式員查bug的思路。還有一種思路是倒過來,從一個最簡的系統,逐漸增加變量,最近确定問題,以後有機會再分享案例。

留一個小思考題:如果第一步删除了where條件後,發現sql不報錯了。應該怎麼查?

如果發現隻有where條件跟select字段同時保留才報錯,單獨修改字段或者删除where條件不報錯,又該怎麼查?

~~積土成山,風雨興焉;積水成淵,蛟龍生焉;~~~