2013年4月14日 星期日

黑白談 (1)–Genero 內到底應不應該 SELECT *

 

解釋一下:
所謂的 SELECT * 是指在程式內,我們使用 SELECT * 的方式,而非一個一個欄位寫明的方式 (如 SELECT imaa01,imaa02,imaa03 FROM imaa_t 的作法)

SELECT * 的前提:
想要做到 SELECT * ,首先要把RECORD定義正確﹝啥?你不是用RECORD,那這種苦行僧行為到哪裡都OK啦﹞。而想要定義正確,大多數人會選擇
DEFINE lc_imaa RECORD LIKE imaa_t.* 的用法

這個用法有好處:萬一今天資料庫的 table 進行 alter 了,那麼重新編譯過後,程式又是一尾活龍。

要是你忘了編譯呢?

那立刻變成一尾活蟲﹝bug - 多貼心,附上自動翻譯﹞

SELECT * 的寫法存在著簡易的好處,但麻煩的事還不只這一樁。要是畫面4fd檔忘了更新,那麼也可能埋下未爆彈﹝欄位在單頭時,有DISPLAY沒有實際欄位並不會出錯,但在單身,可能就出現 List Error (欄位未對齊) 的錯誤﹞。

翻回來說,在過往是否有這樣的例子:程式碼怎麼看都找不到問題,但是經過 rebuild 後,問題居然自動消失。這不是神蹟,這可能是程式內用了 DEFINE RECORD LIKE + SELECT * 所搞出來的。因為當 rebuild 後,一切的程式執行碼 (object code) 都和資料庫內的結構同步了。誰能夠一眼看出這個 42m 是正確的版本?

總上所述,若是考量程式的易察覺 bug 性質,或許應該盡可能地避免使用 SELECT * 的用法﹝幹嘛給 PR 找麻煩呢?不會~ 現在都用產生器了呀~ ﹞,在程式初始開發的階段,辛苦一點,DEFINE 欄位時一個一個的指定,SELECT 也是逐一的對應。

若能做到,或許就能夠在程式編譯時,就直接凸顯錯誤的項目。而不會因為測試上的漏失,不甚將這種 bug 遺留到客戶端,造成不易解說的窘況。

Alerting Sample:
DEFINE lc_imaa  RECORD LIKE imaa_t.*
MAIN
    DEFINE li_cnt  LIKE type_t.num10
    SELECT * INTO li_cnt FROM imaa_t
END MAIN

Adjusting Sample:
DEFINE lc_imaa RECORD
       imaa001 LIKE imaa_t.imaa001,
       imaa002 LIKE imaa_t.imaa002
    END RECORD
MAIN
    DEFINE li_cnt LIKE type_t.num10
    SELECT imaa001,imaa002 INTO li_cnt FROM imaa_t
END MAIN

沒有留言:

張貼留言