読者です 読者をやめる 読者になる 読者になる

今日のバグ

原因不明のバグがあるから見て欲しい、との事だったからコードを眺めてみると・・・

sql += "(";
sql += " ( ";
sql += " COL1 IS NULL ";
sql += "  AND ";
sql += " COL2 IS NULL ";
sql += "  AND ";
sql += " COL3 IS NULL ";
sql += " ) ";
sql += " OR ";
sql += " ( ";
sql += " COL1 = '' ";
sql += "  OR ";
sql += " COL2 = '' ";
sql += "  OR ";
sql += " COL3 = '' ";
sql += " ) ";
sql += ") ";

・・・原因不明?一瞬で気づきましたが・・・


まぁそこは置いとくとして*1
上のコードは同じような事を6回も書かなければならないから、そりゃミスも発生するわな。

(COALESCE(col1, '') = '' AND COALESCE(col2, '') = '' AND COALESCE(col3, '') = '')

こんな感じでNULLチェックを省くと、同じような事は3回に減る。


さらに、col1、col2、col3にNOT NULL制約をかけると、

(col1 = '' AND col2 = '' AND col3 = '')

にまで単純になる。


さらにさらに、col1〜3*2を別のテーブルに切り出すと、より柔軟になる。
最初のテーブルがこんな感じ。

id name col1 col2 col3 ...
1 'AAA' NULL 'hoge' 'piyo' ...
2 'BBB' 'hoge' NULL '' ...
3 'CCC' NULL NULL NULL ...

これを、


Users

id name
1 'AAA'
2 'BBB'
3 'CCC'


UserCols

uid no value
1 2 'hoge'
1 3 'piyo'
2 1 'hoge'


こんな感じに2分割。

NOT EXISTS(SELECT * FROM UserCols WHERE Users.id = UserCols.uid)


まぁここまでやるのはやり過ぎ*3だから、修正はCOALESCEまでにしといたけど。
それより、「ビット演算得意なんだね」って・・・どこをさしてビット演算・・・?

*1:+=とかその他の問題点も置いとくとして

*2:実際は10まであったけど

*3:だってもう稼働してるし、ぐっちゃぐちゃでどこに影響あるか分からないし