カテゴリー別アーカイブ: postgresql

update-select文とupdate-for文について

SQLでもっともつまづきやすいupdate-select文というものがある。

select文による結果でupdateするが、その正しいやり方というのを見ると、おそらく誰もが気持ち悪いと思うはず。

SELECT結果でのUPDATE
qa.atmarkit.co.jp/q/98

setでデータを入れるサブクエリ内のSELECT文のwhere句ではなく、updateの更新対象を絞り込むUPDATEのwhere句をしっかり定義しないと、思った通りに動かないことがある...そして、サブクエリ内のwhere句の条件とupdate文のwhere句の条件は往々にして同じような条件になるため、SQLの文法を知らない人が見ると「何で同じような定義を2回しているんだ?」という疑問を持つことになる。更新先の絞り込みをしないと更新元がない時に問題を起こすので、同じような条件を指定しているのだ。これを解決する手段としてpostgresとしてはupdate文にfor文を連結して更新対象と更新結果を出力するselect文を書くことができる。これによりupdate文にselect文のサブクエリを連結せずにスムーズにデータ挿入することが可能になる。

[postgreSql]PHPの環境にてエラー

HP Fatal error: Uncaught exception 'ADODB_Exception' with message 'postgres8 error: [-1: Missing extension for postgres] in PCONNECT(…

Pconnection関数によるエラーが検出された。

関数のカッコ内による情報で、psqlコマンドでログインできることから、設定情報に誤りはない。さてどうしたものかと調査をした結果、以下の情報にたどりついた。

forums.phpfreaks.com/topic/124493-postgresql-83-php-on-windows/

phpinfo関数で情報を調べたところ、yumによりインストールできるphp-pgsqlが入っていないということが分かった。ただの環境構築ミスでした。

これだけだとエラーが分かりにくいですね。

postgresのデータを別のディレクトリへ移動する(CentOS7/RHEL7の場合)

CentOS7系orRHEL7系にて。

postgreSQLのデータを移動(別サーバからダンプしてリストア)したところ、
容量が足りないというエラーで落ちてリストアに失敗した。

データがどこにあるか調べてみたところ「/var/lib/pgsql/data」だった。

いったん、postgreSQLは停止する。

/varは20GBしか容量がないので1.8TBの容量をとっている/homeの配下へコピーした。

/usr/lib/systemd/system/postgresql.serviceの記述を、

PIDFile=/home/pgsql/data/postmaster.pid
ExecStart=/usr/local/pgsql/bin/pg_ctl -s -D /home/pgsql/data start -w -t 120
ExecStop=/usr/local/pgsql/bin/pg_ctl -s -D /home/pgsql/data stop -m fas

太字のところをdataディレクトリのパスに変更して再起動。

systemctlが自信をリロードせよ(Warning: postgresql.service changed on disk. Run 'systemctl daemon-reload' to reload units.)などと出ることがあるが、
言われた通りにすれば問題なく動作した。

【乾燥】
※当たり前だが、問題なく動作した。そして、簡単だった。
※むかし、失敗がゆるされない時、同一サーバ内でダンプしてからinitdbで新しいデータ保存場所を生成してからリストアするということをしていた。(ディスク容量の問題で同一マシン上での操作ができなかったのでダンプしたファイルを外部メディアに移して作業した)しかし、そんなことをわざわざしなくても大丈夫だった。

[postgresql]select-update文を記述する時の注意点(その2)

select文で取得した条件をもとにupdate文を実行した。

テストデータを1レコード作成した。

select文でそれを取得して、対象の1レコード更新するわけだ。

テストは完璧だと思って、いざ本番環境で動かしたところ動いていない。

…以下のようなエラーが出ていた。

more than one row returned by a subquery used as an expression

テストデータは1件だからうまくいったのであって、
実処理では1件以上のレコードを挿入対象にしたため、
エラーで突き返された…ということらしい。

table_bのidが一意(unique)である時は以下のコードでは問題ないが、
id=1のデータが1件より多い場合は実行されない。

update table_a set data = (select data from table_b where id = 1) where id = 1;

結論:select条件によるupdateは、select条件が複数レコードでないことを確認すること。