とあるSEの戯れ言 このページをアンテナに追加 RSSフィード

2010-09-17

PHP(PDO)+Oracle=too large for buffer and was truncated

ハマったので。

PHP 5.1.6

Oracle 10.2.3

にて。


PDO_OCIでPHPOracleとを繋いでる環境でエラーじゃないけど、Warningが出た。

Warning: PDOStatement::fetch(): column X data was too large for buffer and was truncated to fit it in test.php on line XXX

VARCHAR2のカラムからデータを取得すると出た。

正常にデータが取得出来てるっぽかったけど、おしりの何バイトかが切れてた。

おぉ、trancateされてる。

色々調べてみたところ、全角文字が入ってるとダメだった。

さらに調べてみると、原因が分かった。

OracleSJIS

PHPUTF-8

これが原因だった。


OracleSJISなので、全角文字は2バイト。

PHPUTF-8なので、全角文字は3バイト。


PDO_OCIの場合、テーブルのカラムの型と長さを参照してバッファを決めるようで。

全角文字が入っていた場合、そのバッファが溢れる事があるのです。

なんせ、2バイトだと思っていた全角文字が3バイトだったので。

VARCHAR2(20)のカラムに、全角文字が10文字入っていた場合、SJISならば20バイトなので、OK。

しかし、UTF-8だと30バイトになってしまうので、受け取る側のバッファが溢れてしまう、という事。

対応どうしようか・・・

と考え、

/etc/sysconfig/httpd

をちょっと編集してみた。

# cd /etc/sysconfig/

# vi httpd

export NLS_LANG=Japanese_Japan.UTF8

↓に変更

export NLS_LANG=Japanese_Japan.JA16SJIS

# /etc/rc.d/init.d/httpd restart

Warnningは出なくなったけど、文字化けした。

DBから取得してる根っこの部分でSJISUTF-8の変換をかけようかと考えたのですが、symfony+doctorineという事もあり、断念。

だって、調べるの面倒だから・・・


テーブルのカラム長の定義を1.5倍すれば回避出来るけど、運用案件では無理なので断念。


結果、PDO_OCIのソースをちょっと直して対応する事に。

# cd /usr/local/src

# cd PDO_OCI-1.0

# vi oci_statement.c

510行目付近に有る記述

col->maxlen = data_size;

col->maxlen = data_size*1.5;

# ./configure

# make

# make install

PDOがOracleのテーブルのカラムの長さを取得してる部分で、その長さを1.5倍してあげれば大丈夫。


この対応方法が良いかどうかは疑問が残るが、とりあえずはこれで回避しよう。


でわ。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/momiage3dau/20100917/1284732326