[pgsql-jp: 34062] データサイズの取得方法

satoken satoken @ ma.0038.net
2004年 10月 6日 (水) 01:02:13 JST


 初めまして、satokenと申します。

 初めての質問なので不作法があるかもしれませんがよろしくお願いします。


 Debian 3.0r2 でPostgreSQL 7.2.1を使用しています。

 varchar(n)の様に宣言した列に(nは、実際には整数値) 半角+全角を含む
文字列を登録する際、宣言時に指定した最大バイト数である「n バイト」を越える
文字列を登録しないように予めPHPで制限したいと考えています。

 この際に、制限数をテーブルの変更(例えばn値の変更を伴うテーブルの再定義)を
行ってもPHPの方の変更をしなくて済むようにしたいのです。

 一応、以下の様にしてvarchar宣言した列のサイズを取得できたのですが
取得したatttypmodの値は宣言した値よりも常に4だけ大きかったです。

select attname, atttypmod  from pg_attribute  where attnum > 0
 and attrelid = (select relfilenode from pg_class where relname = 'テーブル名')
 and attname = '列名';

 とりあえず、「atttypmodの値 - 4」が宣言時に指定したバイト数であろう
という推定で使用しています。


質問1.この「4」という値は変わらないものなのでしょうか?
   (既に、PostgreSQLのバージョンが違うと4という数値も変わっている
   という実績があるとか、大きな設計変更がない限り、なかなか変わらないで
   あろう数値なのか...といった感じの質問です)

質問2.この「4」という値を別途select文などで取得する方法は
    ありますでしょうか?(将来、4ではなくなったときに自動的に補正値を得る)


 ここで聞く事ではないのでしょうが、半角+全角を含む文字列のバイト数を
評価するのも一筋縄では行かなそうです。

 PHPにマルチバイト文字関数を組込んでいない場合はPHPのstrlen()関数で
バイト数が得られるようですが、マルチバイト文字関数を組込んでいる場合は
strlen()関数はmb_strlen()関数にオーバーロードされるらしく、
バイト数ではなく文字数が返るようになるため、文字列のバイト数を評価する
別の方法を用意する必要がありそうです。

 以下のようなコードを考えてみましたが(未チェックです)
バイト数を得るために、わざわざ正規表現マッチングを行うという
スマートとは言えない方法しか探せませんでした。

if(function_exists('mb_ereg')){
    //マルチバイト文字関数(mbstring)が組み込まれている
    $str_len_byte = mb_ereg('[.]*', $string, $array);
}else{
    //マルチバイト文字関数は無い
    $str_len_byte = strlen($string);
}


 要は、「データベースのデータ登録時にエラーをさせたくない」
だけなのですが...(尻切れになってもいいからデータは登録したい)
------------------------------
satoken  <satoken @ ma.0038.net>



pgsql-jp メーリングリストの案内