top / index / prev / next / target / source
日記形式でつづる いがぴょんコラム ウェブページです。
SQL Server 2005 JDBC Driver でも必要
blancoDbPhpに向けてメモ , SQL Server 2005 JDBC Driverにおいても selectMethod=cursor オプションは必要です。
Microsoft SQL Server 2005 JDBC Driver 1.1がリリースされていました。ホームページでは 2006.11.30日づけによるリリースということになっています。
このJDBCドライバは、SQL Server 2005への接続に加え、SQL Server 2000への接続もサポートしています。
Microsoft SQL Server 2000 JDBC Driverは selectMethod=cursor オプションを付けて はじめて普通の直感的な挙動をします。これは SQL Server + Java の組み合わせをする人にとっては よく知られた問題です。
強く関連する過去の日記
SQL Server 2000 の JDBCドライバがデフォルトで直感とは大きく異なる挙動をすることは かねてより不思議でした。ところが、SQL Server 2005 JDBC Driverにおいても この点は改善されていませんでした。Microsoft SQL Server 2005 JDBC Driver においても selectMethod=cursor オプションが同様に必要であることがわかりました。このオプションを付けないと、結果セットを取得するとその全件をデータベースからコピーするような挙動をします。これは 通常のデータベースプログラミングに慣れた人にはとても違和感を感じさせる挙動です。たとえば 100万件の結果セットをデータベース上に得ただけで、内部的には まず100万件を プログラミング言語上へのデータ転送が始まってしまいます。
この現象は blancoDbDotNet (.NET Framework版 blancoDb) の試験をしていて OutOfMemoryErrorが発生してはじめて気がつきました。blancoDbは 基本的に 何千万件扱おうが OutOfMemoryErrorは発生しないようなアーキテクチャを採用しています。それなのに Microsoft SQL Server 2005 JDBC Driver を経由して、単なるソースコード自動生成をおこなった だけで OutOfMemoryErrorが発生してしまったのです。ここでようやっと オプションが 2005ドライバでも必要だということがわかりました。SQL Server 2005 JDBC Driverが 2000用のドライバと同様に selectMethod=cursorが必要だったのです。(… blancoDb は 正しく実装されていることがわかって ほっとしました。)
そのような理由から、SQL Server 2000 / 2005 JDBC Driver を利用して blancoDbのソースコード自動生成をおこなう際には selectMethod=cursor をデータベース接続オプションに付与することを強く勧めます。生成速度が大幅に改善する場合があります。
そういえば ADO.NETのデフォルトも データベースカーソルを利用しないで まず全件転送するアーキテクチャがデフォルトであったような記憶がふらふらとよみがえります。マイクロソフト系データベースAPIを扱う際には、この点を気をつけないといけないと 改めて思い知りました。
blancoDbPhpの仕様策定にむけて、まずはPostgreSQL の PHPインタフェースをざっくり調べました。これをメモしておきます。
検索型
pg_send_query (パラメータ無クエリの発行) http://www.php.net/manual/en/function.pg-send-query.php
pg_send_query_params (パラメータ付クエリの発行) http://www.php.net/manual/en/function.pg-send-query-params.php
pg_get_result (結果セットの取得) http://www.php.net/manual/en/function.pg-get-result.php
pg_fetch_object (オブジェクトとしてフェッチ) http://www.php.net/manual/en/function.pg-fetch-object.php ※いくつかのフェッチファンクションがあるのだが、このファンクションが 私には馴染みそうな気がしました。
pg_field_is_null (NULLかどうかの判定) http://www.php.net/manual/en/function.pg-field-is-null.php ※オブジェクトでフェッチすれば NULL判定は不要かも知れません。
メモ: PostgreSQLのPHPインタフェースにおけるパラメータクエリは $1, $2 のような指定方法がある。
実行型
pg_send_prepare (実行型クエリのプリペアー) http://www.php.net/manual/en/function.pg-send-prepare.php
pg_send_execute (実行型クエリの発行。パラメータ付) http://www.php.net/manual/en/function.pg-send-execute.php
気になったAPI
2006.12.29追記 後日談 その後、blancoDbPhpは PDOベースのデータベース入出力をおこなうように方針が変更されました。