« O/Rマッパーが惹き起こす性能劣化(N+1)回避策? | トップページ | PostgreSQLでDBサイズを調べる »

2014.04.25

PostgreSQLでDecode?

「かっしいさん、ポスグレ使えねえよ」
という人がいたので何事かと聞いてみたら
「DECODE関数がおかしいんだよ、こんなのダメだよ!」
とのことだったorz

えっと、懸命な読者諸氏は見当がついたろうが、この発言をした人はORACLE使いである。
まずORACLEにおけるDECODEとは何者か? ということであるが、これはCASE式に良く似た機能を持つ関数である。
然るに、PostgreSQLにおけるDECODE関数は符号化された文字列を復号する関数である。ウェブ畑の人からすればENCODE/DECODEという名称を聞いたらコードの復号.符号化以外の何の機能が実装されるものか、と思うだろう。私も同感である。
最初にORACLEのDECODE関数の存在を知ったときには「はあ? なんかのジョークっすか?」と聞いてしまった記憶があるw
ORACLE畑の人からすれば、私の感想は失礼極まりないことであろう。
実に人間は自分の育ってきた環境に依存するのだなあ。

DECODEを今回使用していたのはこんな感じ。

SELECT kokyaku_id, DECODE(kokyaku_rank, 1, '優', 2,'良', 3,'可', '不可') FROM kokyaku;
こうするとORACLEならkokyaku_rankが1の顧客は'優'という値がくっつく。同様に2なら良、3なら可である。
しかしPostgreSQLのDECODEはあくまで復号関数なので
SELECT DECODE(binary_val,'base64') FROM attached_file;
のように、第1引数が復号対象の文字列、第2引数がDECODEするときに使う元のエンコードである。
なお、先ほどのORACLE用のSQLを実行すると、DECODE関数の引数とあわないので、"そんな関数は存在しない(function decode(unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown) does not exist)"というエラーになる。
この辺はPostgreSQL本体の組み込み関数であってもPL/pgSQLの関数定義などと同様の動作をするようである。

なお、CASE式を使えば標準SQLをサポートしているDBMSなら利用することができる。CASEで書き直せばこんな感じ。

SELECT kokyaku_id
, CASE kokyaku_rank WHEN 1 THEN '優'
WHEN 2 THEN '良'
WHEN 3 THEN '可'
ELSE '不可' END
FROM kokyaku;
となる。分岐が多くなると可読性が低くなるORACLEのDECODE関数を使用するのは慣れの問題もあるのだろうが、個人的には好みではない。
ORACLE使ってるときでもCASEを使うように指摘をして回ってる。

ところでORACLE型のDECODEが使えるDBMSというのも実はいくつかある。
私の知る限りではInformix、DB2、Firebirdかな。
MSSQL、MySQL、SybaseはPostgreSQL同様、Oracle型DECODEは使えないはず。

ORACLEしか使ってない会社にInformix使ったシステムを発注したら(これが間違ってるけど、系列会社なの、察して……)、DECODE関数をめっさ使ったソースが納品されて、速攻返品したのを思い出すw

|

« O/Rマッパーが惹き起こす性能劣化(N+1)回避策? | トップページ | PostgreSQLでDBサイズを調べる »

コメント

得意では無い開発環境(言語等)で、使う前に調べる(聞く)をしない時点でその人の力量が…
と言う話のような気もしますが(笑

投稿: | 2014.08.29 11:49

そういう話なのは間違いないのですが、私にとっては貴重なネタ、もとい視点を提供してくれるので、ありがたいお話です(笑)

投稿: かっしい | 2014.09.01 21:14

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/2022/59527887

この記事へのトラックバック一覧です: PostgreSQLでDecode?:

« O/Rマッパーが惹き起こす性能劣化(N+1)回避策? | トップページ | PostgreSQLでDBサイズを調べる »