[pgsql-jp: 26089] Re: 7.2 ODBC ドライバで SQL_DESC_OCTET_LENGTHを取得すると 0 になる。

Tetsuya Kakura kakura @ saki.netwk.ntt-at.co.jp
2002年 5月 23日 (木) 17:54:34 JST


こんにちは。
加倉です。

お返事ありがとう御座います。

Hiroshi Inoue wrote on Thu, 23 May 2002 16:34:09 +0900

> > ■現象
> > - VARCHAR(40) の列の OCTET LENGTH に 0 が返される。
> > - OCTET_LENGTH の取得は SQLColAttribute で SQL_DESC_OCTET_LENGTH
> > を指定しています。
> >  SQLRETURN は SQL_SUCCESS が返されています。
> > ※参考までに、Column Size, Display Size は各々 40 と 40 が返されて
> > います。
> 
> 
> 問題がいくつかありそうです。
> 
> 1)SQL_DESC_OCTET_LENGTHはODBC3.Xで追加された項目ですが、
>  普通にコンパイルしてもODBC2.50対応のドライバしか作成
>  されません。値の0とSQL_SUCCESSはドライバマネージャー
>  が返しているのではないかと思われます。

unixODBC の SQLColAttribute のソースを確認してみました。
(gdb でのトレースと、ソースの確認)

unixODBC では ODBC 3 の Field Itentifier を 2 の形式に変換しようとして
ますが、OCTET_LENGTH は変換対象がないので、そのまま OCTET_LENGTH を
PostgreSQL の Driver の SQLColAttributes (Attribute ではなく Attributes)
に渡して呼び出しています。

PostgreSQL の PGAPI_ColAttributes のソースも目視で確認しました。
PGAPI_Colattributes は対応する field type (field identifier) がない場合
値の 0 と SQL_SUCCESS を返しています。
field type の場合わけを switch 文で行っていますが、switch 文に default
ラベルがなく、無条件に成功してしまうようです。

> 2) PostgreSQL7.2.xに付属のソースではOCTET_LENGTHに対応
>  する実装がありません。

確かに確認しました。

> 1)についてはODBCVER=0x0300を定義すればODBC3.0対応の
>  ドライバが作成されるかもしれません。残念ながら
>  unixODBCで試したことはないので保証はできません。

PostgreSQL のソースでは、SQLColAttribute も PGAPI_ColAttributes が呼び出
されているようなので結果は同じになると思われます。

> 2)については最新の開発中ソースを使用する必要があります。
>  ちなみに最新の実装では
> 
> > ■加倉の認識
> > - PostgreSQL 7.2.1 では VARCHAR は文字単位になっているので
> > 、OCTET LENGTH (転送に必
> >  要なバッファのバイトサイズ)は、EUC_JP の場合 2(または3)×
> > ColumnSize が戻らなけれ
> 
> はマルチバイト付のコンパイルの場合、無条件に3XColumnSizeが
> 返ります。ただし254(正確にはMax Varchar Size)を超えたら
> 254にしてしまいます。(VAR)CHARが文字単位というのはODBC
> ドライバにとっては厄介な変更で仕方なくこうしてあります。

なぜ OCTET_LENGTH が Max Varchar Size を超えたら 254 バイトに丸められて
しまうのですか?(不勉強ですみません。)
MSDN の以下の URL では、OCTET LENGTH は可変長文字列は最大バイト数を返すと
書かれていますが?
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcsqlcolattribute.asp
ここでいう最大バイト数とは取得するのに必要な転送バッファの最大サイズを意
味しているのだと思いますがどうでしょう。転送バッファの最大サイズなら、254
で丸める意味はないとおもいますが。
OCTET_LENGTH で最大バイト数が分からないと、VARCHAR 型のデータは SQLBindCol
ではデータを取得しずらくなってしまいます。

参考までに、SQLServer のドライバでは NVARCHAR 型(unicodeです)の場合は、
2×ColumnSize をそのまま返すようです。特に値の丸めは行われていません。

宜しくお願いします。

--
Tetsuya Kakura / kakura @ saki.netwk.ntt-at.co.jp



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