←モドル。

OracleのClob型データをJavaのプログラムから操作する.


under construction...


Oracleで文字列を扱うというと,VARCHAR2が一般的(だと思う)が,VARCHAR2は4000文字までという制限がある.(9iの場合.)
しかも,日本語を扱うとなると,NLS?NSL?比みたいのが問題になるらしく,1300字くらいまでしか扱えない.
そこで,CLOBというデータ型を使う.
OracleにはLOB(Large OBject)というデータ型としてCLOBとBLOBがあり,どちらも大きいデータを扱う.
CLOBはCharacterLOB,つまり文字データ.
BLOBはBinaryLOB.画像なんかも扱えるらしい.


[LONG型との比較.]
CLOBと同じように,長い文字列を扱えるデータ型としてLONG型がある.
Oracleとしては,CLOBを扱うことを薦めている.
ということは,これからバージョンが進むにつれてLONGは対象外になる可能性がある.
また,LONGはひとつのテーブルに対して1列にしか使えない.
複数の行に,長文字列を使いたい場合には,LONGは使えない.


[CLOBの不便なところ]
文字列をオブジェクトとして扱うためか,検索の条件にすることが出来ない.
where句で比較することができない.

select * from table_name where where clob_column = xxxx

なんてのは不可.

それに付随して,selectを行う際に,distinct句は使用付加.
なぜかというと,distinctは各カラムに対して,同じかどうかの検証をしているわけで,Clob型はそれができないのだから.というわけ.
ORA-00932というエラーが出る.
”-が予想されましたが,CLOBです.”みたいなメッセージとともに.


[Selectでとってくる]


[Insertで新規登録]


[Updateで更新]
insertは普通に出来るのに,なぜかupdateがうまく出来ない.
正確に言うと,860文字以上くらいをupdateしようとすると失敗する.
それを回避するために考えた苦肉の策.

おおまかな流れとしては,

  1. CLOB以外の部分は普通にupdate.CLOBの部分にはempty_lob()を入れる.
  2. 更新したい行の,CLOB列へのロケータをselect ... for update文で取得する.
  3. 取得したロケータに対して,文字列を書き込む.
こうやってみると何がなにやら....
つまり,一回NULLで上書きしてやって,そこに後から書き込む.ってかんじ.
2回updateを実行するのがポイントかなー...

これだけじゃわからんと思うので,サンプルコードはまた後日.


[既存のテーブルの列を,VARCHARからCLOBに変える(列のデータを消してもいい場合)] 基本的に,テーブルのデータ型というのは,その列が全てNULL出ないと変更できない.
別にデータを消してもいいという場合は,変更はとても簡単.

update テーブル名 set 列名 = ''

で,変更したい列のデータを全て空白にして,

alter table テーブル名 modify 列名 long
alter table テーブル名 modify 列名 clob

とやるだけ.
なぜか,VARCHARからCLOBへの直接変換ができなかったので,LONGをかませている.


[既存のテーブルの列を,VARCHARからCLOBに変える(列のデータを消すのは困る場合)] 前述したように,テーブルのデータ型は,変更対象の列が全てNULLでないと変更できない.
しかしやっぱり,DBなんて動いてるシステムの履歴とったりっていう用途で使っていることが多いので,消せないことが多い.
なので,しょうがないので,テーブルのデータ型を変換するためのプログラムを書いて,それで変換する.

大体の流れとしては,

  1. 変更後のデータ型に対応した一時テーブルを作る. SQL文をつくるのが面倒なのだけど,VARCHARに制約(NOT NULLなど)がついてる場合には,下の方法だと怒られるので(Oracleに.)上の方が確実っちゃ確実.面倒だけど.
  2. 元テーブルからデータをせっせと写す.(VARCHARで読み込んで,CLOBで書く.)
  3. 元テーブルを消す.(or別名で保存.)
  4. 一時テーブルを,元テーブルの名前にrenameする.
実際のサンプルコードは,また後ほど.


←モドル。