PostgreSQL 8.4.xとPHP 5.2.x(5.3.x)の組み合わせでコーディングしていて、いくつか気になったことのメモ。
SELECTした行数を取得するのはpg_num_rows()、INSERT/UPDATE/DELETEした行数を取得するのはpg_affected_rows()
SELECT | pg_num_rows() |
INSERT | pg_affected_rows() |
UPDATE | pg_affected_rows() |
DELETE | pg_affected_rows() |
クエリ結果リソースを食わせてやる関数を間違うとゼロ件になる。例えば、UPDATEした行数を取得しようとpg_num_rows()を使うと0件。
トランザクション処理したいときは、SQL文「BEGIN」「COMMIT」「ROLLBACK」を使う
トランザクション開始 | pg_query($conn, 'BEGIN'); |
コミット | pg_query($conn, 'COMMIT'); |
ロールバック | pg_query($conn, 'ROLLBACK'); |
pg_なんとか関数があるのかと思って関数名ばかり見ていたら絶対見落とすレベル。
繰り返し実行にはpg_prepare()とpg_execute()
実行SQL文をパラメータ化して、$1, $2, ... $nとしておいたものを、pg_prepare()でもって覚えさせる。「pg_prepare($conn, 'hogehoge', 'UPDATE hoge_tbl SET ...');」みたいな。
パラメータ化する際には、$1から順に使わないとWarningが出ます。
$1, $2, ... $nに相当するデータを配列に貯めこむとか、オンデマンドにarray()を書いてもいい。
既存の配列の一部を使う場合は、配列を複写した後array_splice()で余分な要素を省いてしまえばいい。
pg_prepare()で覚えさせたものを、その配列とともにpg_execute()にて実行する。「pg_execute($conn, 'hogehoge', array(a, b, ..));」みたいな。
繰り返しでINSERT/UPDATE/DELETEする場合には重宝します。
文字列の連結でSQL文を作成する古典的なやり方もありますが、NULL値かどうかでSQL分の連結の仕方や演算子の書き方を変えるとか、何かと面倒です。pg_prepare()では括り方を気にしなくてもいいのが良いです。
尚、覚えさせた定義名を忘れさせるには、pg_query($conn, 'DEALLOCATE "hogehoge"');ってやります。pg_なんとか関数はないです。定義名を"〜"のように括ります。
pg_prepare()に失敗したり、あるいは定義名が存在しないのにDEALLOCATEしちゃうと、そのトランザクションが全体的に無効になっちゃうっぽいのです。「Warning: pg_query() [function.pg-query]: Query failed: ERROR: prepared statement "hogehoge" does not exist in 〜」「Warning: pg_prepare() [function.pg-prepare]: Query failed: ERROR: current transaction is aborted, commands ignored until end of transaction block in 〜」っていうWarningが出ますので。