1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【oracle】ROWIDは登録順じゃない

Posted at

こんにちは。
だいぶ前に調べた内容ですが、メモとして残したいと思います。

時々、DBに登録したレコードを登録順に出力してほしいと言われることがあります。
この対応として、ROWIDでORDER BYしておきました!という声を耳にしたことがありませんか。
※筆者も駆け出しのとき、間違えていたと記憶しています。
タチが悪いのは、テストしても登録順に並んでいる時もあるんです。。(←言い訳)

結論から言うと、ROWIDでORDER BYしても登録順に取得できないです。
そもそも登録順に取得したいという要件が、本当に必須かが怪しいのですが、、それは置いておきます。
あえてやるという事であれば、登録順を保持する列を追加する必要があります。

ROWIDがなにかを理解してもらえれば、「ああ、全然違うねー」と分かっていただけるかと思います。

#ROWIDってなあに??#
これに尽きるかと思います。
ROWIDは、どこにレコードの情報があるかというデータの保存場所の情報を保持しています。
内容は、表領域番号、相対ファイル番号、ブロック番号、スロット番号です。
あの謎の長い文字列はデータの保存場所BASE64に変換した文字列です。

ここからちょっと小難しいので、まとめまでサラッと流してもいいです。

・BASE64変換
値をアルファベット(a~z,A~Z)と数字(0~9)、一部の記号(+,/)に置き換える。
バイナリデータを6bitずつ取り出し(足りない分は0を追加)、6ビットとAscii文字の変換表を用いて、4文字ずつにする(4文字に満たない場合は=を追加)。
参考: wiki Base64

・ROWIDの形式:OOOOOOFFFBBBBBBSSS
 O:表領域番号 (データ長:6)
 F:相対ファイル番号 (データ長:3)
 B:ブロック番号 (データ長:6)
 S:スロット番号 (データ長:3)
ROWIDは、これをBASE64変換して格納しているという事になります。

#おまけ#
ROWIDの中身を見てみたいときは、下記で確認できます。

//BASE64のエンコード/デコード
declare
     target   varchar2(255);
     encoded  varchar2(255);
     decoded  varchar2(255);
begin
     -- エンコード対象文字列
     target := 'Hello01!';
     dbms_output.put_line('target=' || target);

     -- base64でエンコード
     encoded  := utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(target)));
     dbms_output.put_line('encoded=' || encoded);
     
     -- base64でデコード
     decoded  := utl_raw.cast_to_varchar2(utl_encode.base64_decode(utl_raw.cast_to_raw(encoded)));
     dbms_output.put_line('decoded=' || decoded);
end;
/

#まとめ#
ROWIDは、データの保存場所の情報です。
登録順でソートするには、登録順を保持する列を追加する必要があります。

以上ですが、ご参考になれば幸いです。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?