ビットのベクトルを数値にする、一次元のビットマップを数値に変換
BIN_TO_NUM ( bit_list )
return [ number ]
- ビットのリスト bit_list を数値に変換した値を戻す。
- SQL、埋め込みSQL で使用可能、PL/SQL に組み込まれていない。(Oracle 11g R2 時点)
ビットリスト
ビットリストは [ bit1 , bit2 , ... bitN ] で指定した 0 と 1 だけを引数としたリスト。ビット列の最大数はおそらく 255 個まで。
BIN_TO_NUM 関数の内容
1 または 0 で構成されるビットのベクトル列 bit_list を指定し、それに該当する数値を戻す。(ビット演算などに使用する)
マニュアルに記載されていないので確かではないが、ベクトルの長さ(パラメータ数)の上限は DECODE と同様に 255 (※1) のようである。
注意
引数の最大としては 255 までとしても 戻り値の NUMBER 型として保証されている最大の精度は 38桁(※1) まで
255個 のビット列を指定してもエラーにはならないがビットのパターン次第では正しい数値は得られないということになる。
ちなみに
2^256 = 約 1.15792089×10^77
2^126-1 = 85070591730234615865843651857942052863 が 38桁の限界
(※1) 全プラットフォームで NUMBER 型で「保証されている」精度は 38桁であるが 39〜40桁までは保持できる。
SELECT BIN_TO_NUM(1,1,1,1,1,1,1,0) FROM DUAL
⇒ 254
SELECT BIN_TO_NUM(0,...,1 (計 256)) FROM DUAL
⇒ ORA-00939: 関数の引数が多すぎます。
微妙な引数をもつ BIN_TO_NUM の使い道
BIN_TO_NUM は入力パラメータが可変長なのでビット文字列変換機能としては微妙な使い心地である。
しかし、これは非正規化のテーブルに対して操作を行なう意図が重視されたものなので2進数を10進数に変換する目的にするのはあきらめよう。
(データウェアハウスなどの非正規化状態のビットマップデータの抽出に使う)
例として宅配便の配送希望時刻を考える。午前9時から午後9時までを3時間区切りで分割して非正規化状態で保存しているとする。
配送のデータは「9時〜12時まで」、「午後以降、午後18時まで」、「夜間」、「終日」として以下のようなフラグで管理しているとする。(このように非正規化してよいかは無視してほしい)
配送番号(no) | 9時-12時(a) | 12時-15時(b) | 15時-18時(c) | 18時-21時(d) |
001 | 1 | 0 | 0 | 0 |
002 | 0 | 1 | 1 | 0 |
003 | 0 | 0 | 0 | 1 |
004 | 1 | 1 | 1 | 1 |
このとき 9時から12時までに届ける荷物を抽出するときに
select no from tablename
where
bitand(bin_to_num(a,b,c,d), bin_to_num(1,0,0,0)) <> 0
のようなビットマップの配列の変換と ビット演算処理関数 を使用することで比較的簡単にデータを抽出することができる。
引数の制限
SQL 関数 - BIN_TO_NUM 関連