memorandums

日々の生活で問題解決したこと、知ってよかったことなどを自分が思い出すために記録しています。

Posgresqlでは文字列型のカラム値がNULLの場合は比較演算子が使えないらしい

以下、デバッグ作業の記録です。この結果わかったことはタイトルの通りです。以下を読んでもそれ以上の情報はありませんので。。。

演習授業ではsqlite3がメインで、開発したアプリをデプロイ演習するときにpostgresqlをちょっと利用する程度でした(Heroku&Render.com)。

昨晩、就寝前に開発中のRailsアプリをプッシュして実行してみるとあるページだけがなぜか表示されません。エラーもでません。あれれ。。。夜中だったのでダウンzzz

今朝、朝食後、再挑戦して調べてみることに。

Render.comはpostgresqlなのでDBツール(Postico2)で接続して中身を見たもののおかしいところはありませんでした。エラーが出ないエラー、これが辛いですねぇ。

Render.comにSSH接続して確認したいが無料プランだとそれができない。有料使いたいところですが研究費で契約するのが面倒。契約とか支払いとか研究用のカードを持たせてもらって簡単に使えるようになったらどんなに楽か。不正利用があるから面倒になる。しかたがないですね。。。この辺をAIがサポートしてくれるようになったら本当に楽でしょうね。でも常にAIに人間の行動が監視されるようになる。。。とも考えられますから、それは嫌ですけどね。個人情報をどんどん抜かれている現代では実質もうなっているようなものか😅

余談ですが、大学教員って事務処理ってあまりしない印象かと思いますが、元サラリーマンがいいますがそんなことはありません。事務スタッフを雇っていらっしゃるような優秀な方は別として、個人営業ですから、ほとんどの事務処理を一人でやらなければなりません。

話を戻して。

Webページを眺めていても何もわからないので、とりあえずRender.comのログを見ることに。

問題ページを表示したときに実行されるコントローラのSQLのログをみて見ました。

Active Recordが実行したSQL文が表示されていたので、それをDBツールで実行してみました。Active RecordのSQLなので文法としては当然正しいわけですが、意図したように動作していない可能性があります。

正しいと思っていたSQLの実行結果は0件

おいおい。。。(再現できたのはもちろんラッキー🎉)。

そのSQLからWHERE句の条件を1つずつ追加しながら様子を見ました。

ある項目をつけたら0件に。なるほど。以下の条件が悪さしているんだな、とわかりました。statusはVARCHAR。なぜ?

status != ‘Completed’

statusの項目をDBツールで見るとNULLになっているところもありました。

そうか。。。もしかしてNULL値は!=判定できないのか?

試しに条件を以下に変更したら表示されました。ビンゴです。

(status is null or status != ‘Completed’)

なるほど。

ググってみると確かにpostgresqlでは文字列比較はNULLに対しては効かないらしい。

www.enterprisedb.com

とりあえずSQL文を変えないと。。。とActive Recordのメソッドで頑張って書いてみたのですがORのときの範囲をカッコで指定するのがよくわからず、結局、以下のようにwhereメソッドにSQLを直書きしました。

Err.where("uid = '#{params[:id]}' AND error_msg_key <> '200' AND (status is NULL OR status <> '#{SEL_COMPLETED}')").order(created_at: "DESC")

考えてみれば初期値がNULLになるのがそもそも悪い気がします。CREATE TABLEするときにDEFALUT値を設定しておけばこんなハマり方はしないですね。。。

まぁ一週間もすれば忘れてしまうようなことですがつまずきからの発見でした。