PHP + PostgreSQL
■ このスレッドは過去ログ倉庫に格納されています
0001りさあ
NGNG0109名無しさん@お腹いっぱい。
NGNG判らず困っております。
フォーム(test1.php3)からデータを受取り、それをデータベース(Postgre SQL)
へ登録する際、それを処理するページがtest2.php3とお考え下さい。
登録用フォームにはtext形式でname="cr"という項目にデータを入力
してもらいます。
因みにPostgre SQL側ですが、crにはNull不可としてあります。
ここでデータ登録は問題なく処理が出来ました。
しかし、もしデータが何も入っていない時と、test1.php3をブック
マークとかに登録されていた場合には、直接このページへ入って来
た時にエラー表示を出したいと思いました。
そこでただinsert処理をしていたスクリプトにエラー処理用のスクリ
プトを追加してみたいと思ったのですが、どうにも上手に処理出来ま
せん。
この場合、以下のスクリプトで解決する方法はどうすればいいでしょ
うか?
// ここにfunctionを設定?
if(ここに何をいれるのか?)
{
print('エラーです'\n);
}
ellse
{
現在使用しているinsert処理用のスクリプト
}
宜しくお願いいたします。
0110109
NGNG自分で解決出来たと思われます。
ついWindowsの癖で、フォームで使用するタグにvalue="$cr"を入れておらず、
それが問題だったような気がします。
if($cr == "")
{
print("エラーです\n");
}
else
{
insertの処理
}
で問題なさそうな気がします。(現在テストした結果ですが)
何か問題があるような場合、ご指摘いただけましたら幸いです。
0111名無しさん@お腹いっぱい。
NGNG電動ナナシさんありがとうございました。
ちょっとむずかしくて解りませんでしたけど。
もしよかったらなんかサンプルコードありませんか?
例えばpg_userにアクセスするような。
HTTPがわかりやすすぎるのでしょうか?はぁ。
0112Error 401
NGNG$ cvs update
P common.php
P mysql.php
P odbc.php
P oci.php
common.php以外は、PostgreSQLには関係無いけど :-P
ちなみに私はPEARに全面移行しました。
0113Error 401
NGNG持続的接続を使ってる人います?
なんか、動きがおかしいんです。
1. php.ini : pgsql.max_persistentの値より、プロセスが増える。
2. 'now'::timestampの値がおかしい。
1.は、テストとして10を設定してるんですが、プロセスが10を超えてしまいます。
どこまで増えるかは不明。
2.は、ストアードファンクションの中で、
insert into tbl(col) values('now'::timestamp)
とやると、過去のtimestampが記録されることがあります。
ひょっとすると、過去に立ち上がったプロセスに接続されると、
この現象が起きるのかもしれませんが、良くわかりません。
・・・というわけで、現在は持続的接続は使っていません。
でも持続的接続にすると、ページあたり、-30ms位になるんだけどなぁ。
0114名無しさん@お腹いっぱい。
NGNG持続的接続はhttpdのpidごとに張るんですよね。
だからプロセスが変わるってのは変なのではないでしょうか?
ストアドだから張ったときのnow読んでいるって言う可能性は
ないのでしょうか?
この板にがんばって発言してみようと思ってるんですけど
ほんとど素人であーぱーナこといってすいません。
0115電動ナナシ
NGNGソース見たけどよくわからんなあ。
チェックは働いているみたいなんだけど。
全プロセスで pConnect() してるの?
どこかで Close() したりしてない?
daemontools 使って PgSQL 側の接続状況調べて、同時に何コネクション
張りにきているか調べてみたら?
http://tanaka-www.cs.titech.ac.jp/~euske/doc/daemontools.html
0116Error 401
NGNGうーん、昨日から持続的接続のテストを始めて、
今日になって、'now'::timestampに昨日の日付のものが
登録されるようになったんです。
サーバは、昨日から立ち上げっぱなし、
クライントは、今日立ち上げたもの
です。
持続的接続は、クライアントがいなくなった場合、そのプロセス
は残っていて、接続要求があったときに、空いてるプロセス
があれば、そこにつなげる、というふうに思ってたんですが、
間違いでしょうか?
0118Error 401
NGNGdaemontoolsは、ちょっとスケジュールが厳しいので、
インストールして、調査、っていうのは厳しいなぁ。
来週火曜日までに、ひととおり作り上げ、来月稼動なので。
来週火曜日で承認されたら、また調査してみます。
0119電動ナナシ
NGNGいいよね。で、close() すると持続的接続でも接続解除されるというのも
いいよね。
で、持続的接続の場合には次のようになる。
例えば pgsql.max_persistent = 2 とするよ。
最初に pConnect() するよね。
・PHP の持続的接続数 = 1
次に pConnect() するよね。
・PHP の持続的接続数 = 2
次に pConnect() すると失敗
・持続的接続数 > max_persistent が成立
でも、次の場合はうまくいく。
最初に pConnect() する。
・PHP の持続的接続数 = 1
次に pConnect() する。
・PHP の持続的接続数 = 2
どれかがいったん close()
・PHP の持続的接続数 = 1
次に pConnect() する。
・PHP の持続的接続数 = 2
こんな感じになると思う。間違っていたらスマン。
0120電動ナナシ
NGNGpConnect 関数は、過去の接続を覚えていて
・以前接続したのと同じコネクションがあれば、それを再利用
・そうでなければ接続
を行う。
で、「以前と同じ接続」かどうかは
"pgsql_HOSTNAME_PORT_OPTIONS_TTY_DBNAME"
という文字列で判断される。つまりホスト名、ポート番号、接続オプション、
端末名、データベース名の組み合わせがいっしょなら同じ接続、
そうでなければ別の接続になる。
pgsql.max_persistent は上記組み合わせの個数を制限するもの。
仮に Apache のプロセス数が 100 あっても、同じホストの同じ DB に接続
するなら、コネクションは一つしか張られないから max_persistent の
制限にはひっかからない。
あるコネクションへのアクセスが許可される Apache のプロセス数ではないよ。
0121電動ナナシ
NGNG・セッション確立のコストが大きい(メモリと CPU に負荷を与える)
・WWW の場合、リクエスト単位で接続するとセッション確立・破棄が
頻繁に行われることになり、さらに負荷がかかる
から。
で、複数リクエストを一つのデータベースセッションで処理することで
この問題を解決しようということで、持続的接続というアイデアが
生まれたんだよね。確かもともとはミドルウェア(トランザクション
モニタの Connection Pooling 機能)だと思った。
0122Error 401
NGNG> いいよね。で、close() すると持続的接続でも接続解除されるというのも
> いいよね。
ん、勘違いしてました。
close()で接続解除されるのは、あくまでも「仮想接続(勝手に名前
付けました)」で、httpd <-> postgresの接続は残るものだと思って
ました。じゃないと、postgresのプロセスが死なないことに説明
がつきません。
そもそも、close()しても、このpostgresのプロセスが残る、という
のが、何かおかしいのでしょうか?
# OracleのBC4Jにおけるコネクションぷーリングの考え方とは
# かなり違うなぁ。
※仮想接続とは、ブラウザ <-> httpdのHTTPセッションを越えた、
複数HTTPセッションにまたがる、仮想的なDBコネクションを
指しています。
> "pgsql_HOSTNAME_PORT_OPTIONS_TTY_DBNAME"
> という文字列で判断される。つまりホスト名、ポート番号、接続オプション、
> 端末名、データベース名の組み合わせがいっしょなら同じ接続、
> そうでなければ別の接続になる。
うーむ、テストは同じクライアントから、同じデータベースへの
接続を、同じユーザ名、パスワードで繰り返すものだったから、
やっぱりPostgresのプロセスが増殖していくのは納得いきません。
# PostgreSQL 7.1RC1出てますね。
0123電動ナナシ
NGNGPostgres が残るってのは不思議だなあ。勘違いしてるかもしれないので、
ちょっと調べてみる(ちゃんと確認しているわけじゃなかったので)。
PostgreSQL と Apache/PHP は同じサーバーで動いているの?
lsof 入れてみて、どの Postgres プロセスが誰とお話しているか調べて
みたらどうだろ?
0124Error 401
NGNG電動ナナシさん、いつもどうもです。
なんか、お手間を取らせてしまってすみません。
今、とんでもなくテンパッテるので、私の方の再試は水曜日以降に
なります。
0125名無しさん@お腹いっぱい。
NGNG> 2.は、ストアードファンクションの中で、
> insert into tbl(col) values('now'::timestamp)
> とやると、過去のtimestampが記録されることがあります。
これは、'now'::text にしなくちゃ、って話じゃなかったらスマソ
0126Error 401
NGNG.> これは、'now'::text にしなくちゃ、って話じゃなかったらスマソ
むむ。
test=# select 'now'::text;
とやると、
?column?
----------
now
(1 row)
となるのですが・・・。
# PostgreSQL 7.1beta6です。
# 運用開始までに、7.1出るのだろうか・・・。
0127名無しさん@お腹いっぱい。
NGNGいや、そうじゃなくて、トリガーとかで 'now'::timestamp って
するとトリガー生成時点の 'now' になっちまうんで、'now'::text
にしとくって話。
0128Error 401
NGNGあっ。理解できました。
で、いろいろ調べたんですが、
CURRENT_TIMESTAMP -- SQL92準拠
now() -- PostgreSQL固有?
'now'
のどれでも、現在時刻を返してくれます。
> いや、そうじゃなくて、トリガーとかで 'now'::timestamp って
> するとトリガー生成時点の 'now' になっちまうんで、'now'::text
> にしとくって話。
そういえば、この話どこかで見覚えがあるんですが、
マニュアルに載ってるのですか?
マニュアルは、ローカルでNamazu化してるんですけど、
検索できませんでした。
0130Error 401
NGNG[環境]
PHP 4.0.4pl1 (pearはCVS currentのもの)
PostgreSQL 7.1RC1
使ったソースは以下。
-- test.php ---------
<?php
&nbsp;&nbsp;require("DB.php");
&nbsp;&nbsp;$db = DB::connect("pgsql://localhost/test", true);
&nbsp;&nbsp;if (DB::isError($db)) {
&nbsp;&nbsp;&nbsp;&nbsp;echo "Connect failed.";
&nbsp;&nbsp;&nbsp;&nbsp;exit;
&nbsp;&nbsp;}
&nbsp;&nbsp;echo "Connect success.";
&nbsp;&nbsp;$db->disconnect();
?>
----------------------
PostgreSQLは、
pg_ctl start -o -i
で起動。
-- php.ini -------------------
pgsql.allow_persistent = On ; allow or prevent persistent link
pgsql.max_persistent = 10 ; maximum number of persistent links. -1 means no limit
pgsql.max_links = -1 ; maximum number of links (persistent+
-------------------------------
続く。
0131Error 401
NGNG→postgresのプロセスは残ったまま
・そのまま何回かリロードしてみる。
→postgresのプロセスは残ったまま。ただしプロセス数は増えない。
・時間を置いてリロードしてみる。
→規則性はわからないが、あるタイミングでプロセスは増えていく。
・どこまで増えるかはわかりません。
ps -ef | grep postgresの結果
postgres&nbsp;19528&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;0&nbsp;09:27&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;00:00:00&nbsp;./postmaster&nbsp;-D&nbsp;/usr/local/pgsql
postgres&nbsp;23715&nbsp;19528&nbsp;&nbsp;0&nbsp;10:02&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;00:00:00&nbsp;postgres:&nbsp;nobody&nbsp;test&nbsp;127.0.0.1
postgres&nbsp;23723&nbsp;19528&nbsp;&nbsp;0&nbsp;10:04&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;00:00:00&nbsp;postgres:&nbsp;nobody&nbsp;test&nbsp;127.0.0.1
postgres&nbsp;23813&nbsp;19528&nbsp;&nbsp;0&nbsp;10:12&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;00:00:00&nbsp;postgres:&nbsp;nobody&nbsp;test&nbsp;127.0.0.1
postgres&nbsp;24841&nbsp;19528&nbsp;&nbsp;0&nbsp;10:26&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;00:00:00&nbsp;postgres:&nbsp;nobody&nbsp;test&nbsp;127.0.0.1
続く。
0132Error 401
NGNGとりあえずオプション無しの結果。
postmaste&nbsp;24841&nbsp;postgres&nbsp;&nbsp;mem&nbsp;&nbsp;&nbsp;&nbsp;REG&nbsp;&nbsp;&nbsp;3,65&nbsp;&nbsp;1651925&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;817675&nbsp;/home2/local/pgsql7.1RC1/bin/postgres
postmaste&nbsp;24841&nbsp;postgres&nbsp;&nbsp;mem&nbsp;&nbsp;&nbsp;&nbsp;REG&nbsp;&nbsp;&nbsp;&nbsp;3,7&nbsp;&nbsp;&nbsp;492888&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;180226&nbsp;/lib/ld-2.1.3.so
postmaste&nbsp;24841&nbsp;postgres&nbsp;&nbsp;mem&nbsp;&nbsp;&nbsp;&nbsp;REG&nbsp;&nbsp;&nbsp;&nbsp;3,7&nbsp;&nbsp;&nbsp;&nbsp;79474&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;180244&nbsp;/lib/libcrypt-2.1.3.so
postmaste&nbsp;24841&nbsp;postgres&nbsp;&nbsp;mem&nbsp;&nbsp;&nbsp;&nbsp;REG&nbsp;&nbsp;&nbsp;&nbsp;3,7&nbsp;&nbsp;&nbsp;197984&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;180288&nbsp;/lib/libresolv-2.1.3.so
postmaste&nbsp;24841&nbsp;postgres&nbsp;&nbsp;mem&nbsp;&nbsp;&nbsp;&nbsp;REG&nbsp;&nbsp;&nbsp;&nbsp;3,7&nbsp;&nbsp;&nbsp;523855&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;180236&nbsp;/lib/libnsl-2.1.3.so
postmaste&nbsp;24841&nbsp;postgres&nbsp;&nbsp;mem&nbsp;&nbsp;&nbsp;&nbsp;REG&nbsp;&nbsp;&nbsp;&nbsp;3,7&nbsp;&nbsp;&nbsp;&nbsp;72276&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;180272&nbsp;/lib/libdl-2.1.3.so
postmaste&nbsp;24841&nbsp;postgres&nbsp;&nbsp;mem&nbsp;&nbsp;&nbsp;&nbsp;REG&nbsp;&nbsp;&nbsp;&nbsp;3,7&nbsp;&nbsp;&nbsp;545453&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;180228&nbsp;/lib/libm-2.1.3.so
postmaste&nbsp;24841&nbsp;postgres&nbsp;&nbsp;mem&nbsp;&nbsp;&nbsp;&nbsp;REG&nbsp;&nbsp;&nbsp;&nbsp;3,7&nbsp;&nbsp;&nbsp;174341&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;639164&nbsp;/usr/lib/libreadline.so.4.0
postmaste&nbsp;24841&nbsp;postgres&nbsp;&nbsp;mem&nbsp;&nbsp;&nbsp;&nbsp;REG&nbsp;&nbsp;&nbsp;&nbsp;3,7&nbsp;&nbsp;&nbsp;&nbsp;14837&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;180309&nbsp;/lib/libtermcap.so.2.0.8
postmaste&nbsp;24841&nbsp;postgres&nbsp;&nbsp;mem&nbsp;&nbsp;&nbsp;&nbsp;REG&nbsp;&nbsp;&nbsp;&nbsp;3,7&nbsp;&nbsp;5309068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;180230&nbsp;/lib/libc-2.1.3.so
[考察]
うーん、全く進歩なし(^^;
0133Error 401
NGNGさっきのプロセスが残っている状態で見てみると、
Active Persistent Links 0
Active Links 0
disconnect()なしでスクリプトを実行すると、
Active Persistent Links 1
Active Links 1
その状態で、disconnect()すると、
Active Persistent Links 0
Active Links 0
プロセスは1個増えました。
ちなみに、これらのプロセスは24時間たっても消えません。
Apacheを止めると消えます。
[考察]
PHPの持続的接続のリンク数の管理はうまくいっているみたい。
プロセスの生成・消滅条件は、いまだわからず。
0134Error 401
NGNG報告しておきます。
結局、現状理解の糸口さえ見つからない状態なので、
持続的接続を使うのは、とりあえず止めます。
PHP4.0.5 + PostgreSQL7.1がそろったあたりで、再チャレンジします。
0135Error 401
NGNG仕事の合間に、いろいろとWebを検索してみたら、
「postgresプロセスが死ぬのは、対応するapacheプロセスが
死んだとき」
という情報にあたりました。
どっかの英語のBBSです。
今使っているサーバは、apacheを起動すると、apacheのプロセスが
10個立ち上がります。
で、これに空きがある場合は、HTTPリクエストをこれらのプロセスが
処理します。HTTPセッションが終了しても、これらのプロセスは
残ったままです。
持続的接続で立ち上がったpostgresプロセスは、これらのプロセス
との間に、DBセッションを確立します。
だから、close()しても、postgresプロセスは残ったままなんです。
・・・という線で自分を説得。多分正解。
0136電動ナナシ
NGNGソースちょっと追ったけど、connect() の場合と pconnect() の場合とで
ほとんど同じ処理をしているんだよね。単にリンク数のカウンタ処理部分が
違うくらいで。
connect() だと postgres は死んでくれるの?
謎だあ。もうちょっと追ってみよう。
# 暇ができたらだけど・・・。
0137Error 401
NGNG>connect() だと postgres は死んでくれるの?
はい、死んでくれます。
>謎だあ。もうちょっと追ってみよう。
念の為書いときます。
configure optionの --enable-sigchildが、Oracleの持続的
接続を使う場合には必要という情報を見つけ、
リコンパイルしてみたんですが、これは関係ありませんでした。
オプション無しの場合と全く同じ挙動でした。
0138電動ナナシ
NGNGなんとなく原因がわかった雰囲気。
ひょっとして PostgreSQL だけでなく、あらゆる持続的接続の Close が
きちんとされてないという予測を立てたんだけど、追試できる人っている?
0139名無しさん@お腹いっぱい。
NGNGclose で close されたら、pconnect の意味なし
0140電動ナナシ
NGNG馬鹿さらしてしまった。鬱だし脳。
0141名無しさん@お腹いっぱい。
NGNGバックエンドをpreforkさせるための便宜的手法。
fastcgi みたいなものと言った方がわかりやすい?
0142Error 401
NGNGしかし、話題になりませんね・・・。
0143電動ナナシ
NGNGPostgreSQL の場合、ホビーよりビジネスでの利用が多いから、
安定性が確認されていないベータ版には興味がないのかもしれないね。
そういえば PHP-jp に pConnect() 時の Backend の数を質問していた人が
いたけど、回答がなかったね。
あと一応確認。そんなことも知らんのかって言われそうだけど・・・。
Module 版の PHP の場合、Apache で fork() された分だけプロセスが
あると思っていいんだよね?。例えば Process ID が 1000 な httpd と
1001 な httpd がある場合、httpd に組み込まれた PHP はそれぞれ
別々のプロセスとして動作するんだよね。
そうだとすると persistent_links や max_links は httpd プロセス
ごとに効くことになるから、Process 数 x {persistent|max} links に
なるのは当然ということか。
# これらの数字は PHP/Zend Process ごとに保有されるみたい。
0144名無しさん@お腹いっぱい。
NGNG>PostgreSQL の場合、ホビーよりビジネスでの利用が多いから、
>安定性が確認されていないベータ版には興味がないのかもしれないね。
7.1前提でシステムを作っている私って・・・
# 4/23リリース予定。それまでにRelease版出るかなー?
>そういえば PHP-jp に pConnect() 時の Backend の数を質問していた人が
>いたけど、回答がなかったね。
すぐに自己フォローしてたから・・・。
ちなみに、あれは私じゃありません。
>Module 版の PHP の場合、Apache で fork() された分だけプロセスが
>あると思っていいんだよね?。例えば Process ID が 1000 な httpd と
fork()って、PHPのプロセスのことですか?
だったら、fork()はしないと思いますが・・・。
# ここ、暇なときにDSOの仕組みをもう一度調べて、間違ってたら訂正します。
異なるhttpdに接続されたHTTPセッションは、全く関連性が無いと
思います。
# これも、後日訂正の可能性あり。
0145電動ナナシ
NGNG> fork()って、PHPのプロセスのことですか?
いや、httpd のプロセスのこと。
さっきマニュアル見たらちゃんと書いてあった。httpd の Child Process ごとに
永続的接続するよって。
鬱だし脳。
http://www.php.net/manual/ja/features.persistent-connections.php
0146名無しさん@お腹いっぱい。
NGNG来は英数字のみの組合せ)を入力してもらい、それをPHPを通じてPostgreSQL
からデータをピックアップ予定です。
この$test_idがselect文において
select * from t_test where test_id = $test_id
としてデータをピックアップする際の判断材料です。
しかし、フォームの場合だと何も入力しないで送信したり、2文字
と指定していても1文字しか入れないなど、色々問題が考えられま
すよね?
で、それらはPHP内にエラー処理スクリプトを書いて、自分では
「完璧!」とか思っていたのです。
でも、ちょっと不安だったので、色々とフォームに英数字以外に
記号など(*や!などなど)を入れると、エラーが出ることが判明
しました。
このような記号が入力されたとき、何か上手にエラー対処する方
法などを教えていただけませんでしょうか?
0147名無しさん@お腹いっぱい。
NGNGereg()とかpreg_xxxx()などの正規表現ライブラリ関数を使って、
妥当性チェックしてみてはいかが?
0148146
NGNG早速ereg("[[:alnum:]]{2}", $test_id)として、ちゃんと指定の
形で英数字2文字だけが入力されているかを判定させてみました。
無事考えていたことが出来ました。
ありがとうございます。
0149名無しさん@お腹いっぱい。
NGNGereg()の正規表現って気持ち悪いね
0150名無しさん@お腹いっぱい。
NGNG149って気持ち悪いね
0151名無しさん@お腹いっぱい。
NGNG>安定性が確認されていないベータ版には興味がないのかもしれないね。
つーか、ほいほい導入してもデータの移行が大変なんだよ
0152名無しさん@お腹いっぱい。
NGNGサイトはありますか?
0153名無しさん@お腹いっぱい。
NGNGどなたかご親切なアドバイスをいただけませんか?
フォームからInsert用のデータを受取り、それを処理するファイルがhoge.php3
とします。
フォームからのデータ自体をphp3利用でPostgreSQLにInsertすることまでは出
来ました。
しかし、このままでは本当にそのデータがちゃんとデータベースに登録されたのかど
うかがフォームに書き込んだ人は判りませんから、同じhoge.php3にデータ登録後
に今度は今ちょうど登録したデータはこれでいした、みたいに表示させたいのです。
でも、それを簡単に処理する方法がどうしても思い付きません。
是非この簡単・初歩の初歩だとは思うのですが、それすら判らない厨房に是非暖かい
アドバイスをいただけませんでしょうか?
0154名無しさん@お腹いっぱい。
NGNG$result = pg_exec($sql);
if($result){
echo "登録したデータは$hoge";
}
0155Error 401
NGNGどこが判らないのかが良くわかりませんが、
pg_getlastoid()
を使えば、pg_exec()でInsertされたオブジェクトのoidを取得できます。これで、
select * from table_name where oid = $last_oid
とすれば、今Instertしたタプル(行)を取り出せます。
それとも、取り出したタプルを簡単に表組して表示する方法がわからない
のかな?
0156名無しさん@お腹いっぱい。
NGNG私もそれでいいと思います。
同時にinsert,selectの部分はトランザクション入れた方がいいかも。
oid取得後selectして、
表組みが面倒ならpg_fetch_array($r,$row)で配列に格納して
テンプレートファイルに埋め込むという手も。
見栄えはいいかも・・。
0157153
NGNG>>155
>>156
皆さん本当にありがとうございます。
PHPの本を買って、色々関数を探してみているのですが、実際にそれ
らをどう活用するのかが今ひとつ理解しきれていません。
今晩家に帰って早速皆様から教えていただきました方法を試してみ
ます。
結果はまた今度お知らせします。
0158PHP-jp観察者
NGNGより引用。
-----------------------------
ってな、環境のシステムのプログラムを引き継ぐ事になってプログラムの改良を
行っているのですが、以下の様なコードで2回目のpg_execで処理が戻るまで
約40分くらい掛かってしまいます。
----------------------------------------------------------------------
$sql1 = "SELECT * FROM usertable WHERE syumi='".$syumi_data."'";
$user = pg_exec($conn, $sql1);
$row = pg_numrows($user);
$temp = "user_id in ('".pg_result($user, 0, user_id);
for ($j = 1; $j < $row; $j++) {
$temp = $temp."','".pg_result($user, $j, "user_id");
}
$temp = $temp."')";
$sql2 = "SELECT * FROM maintable WHERE ".$temp." ORDER BY user_id";
if (false == ($main = pg_exec($conn, $sql2))) {
echo "検索失敗";
return false;
} else {
echo "検索完了";
}
----------------------------------------------------------------------
原因は、前のpg_execで見つけてきたuser_idが7000件近くあって、
-----------------------------
joinを知らない奴、逝ってよし。
しかも質問者は、selectを中止させる or postgresプロセスをkillする
方法を探してるときたもんだ。
0159153
NGNG実は私が質問する際、PHP-jpと2ちゃんねるのどちらで聞こうか
迷いました。
最終的にこちらで教えてくれる人達の方が凄く親切・丁寧である
ような気がして、昨晩書き込みした次第です。
なんだかPHP-jpだと、初心者だと突き放されそうな気がして、ど
うも尻ごみしてしまいます。
0161電動ナナシ
NGNGこれはちょっとショッキングだなあ。
SELECT m.user_id, .... FROM usertable u, maintable m WHERE u.user_id = m.user_id
AND u.syumi = :SYUMI ORDER BY m.user_id;
ってするだけの話だよね。
さっき pgsql にも流れてきたけど、根本的に SQL が分かっていないねえ。
0162Error 401
NGNGどんな言語が出ても、こうする人たちは一生こうしていくんだと思う。
で、「このSQL文投げると○○分帰ってきません」とかなる。
ちょっとSQL勉強して、各DBエンジンのクセやコスト算出方法を知れば
こんなことなくなると思うんだけど。
この間、ちょっとかかわった某大規模システムもそんな感じで設計されてた。
JOINを知らないのはおろか、数千レコードのあるカラムの合計を取ってくるのに、
数千回ループして、+=してた。
しかも、それ、Webシステムのサーバアプリ部分。どうなったのかな、アレ。
0163153
NGNGたまたま話題としてPHPの判る人でなければ煽れない(のかな?)
ということで、本当に煽ラーがいなくて助かります。
逆に皆さんの書き込み見ていると、欲しいと思っていた答えがズ
バリと回答されてたりしますので、この板を色々参考にさせてい
ただいてます。
0164名無しさん@お腹いっぱい。
NGNGinsert 直後なら、プライマリキーも保持したまま
だろうから、それを where につっこんだら
いいんじゃないのかな・・。
oid は、索引されてなくて遅い。
0165名無しさん@お腹いっぱい。
NGNG0166153
NGNG>>156
教えていただきましたことを参考に、以下の様に作成しましたがエラー表示です。
多分私の設定が違うと思うのですが、最後にselectする際の条件でwhere oid = $last_oid
部分がダメなのか?、という気がしてます。
というのも、テーブル自体にはoidというフィールドがないので、何を参照しているの?、と怒られ
ているのではないかと考えました。
因みにphpは以下の様に書いております。
$sql_1 = "insert into test values ('hoge');
$result_1 = pg_exec($conn, $sql_1);
$last_oid = pg_getlastoid($result_1);
if ($last_oid != 1)
{
結果を表示するテーブル作成
}
else
{
エラー表示
}
実行したとき、parse error in xxxxxx on line 103と出まして、103行目が上記における
select文のフレーズなんです。
どこで私は大きな間違いをしでかしてますでしょうか???
0167名無しさん@お腹いっぱい。
NGNG0168153
NGNG一応テーブル内にはIDというフィールドを設けております。
上記の例ではinsert部分で省略して書いてしまいました。
IDはprimary keyで、自動的に番号を振るようにtest_id_seq
を設定してあります。
0169153
NGNGsql_1 = "insert into test values ('hoge');
$result_1 = pg_exec($conn, $sql_1);
$last_oid = pg_getlastoid($result_1);
if ($last_oid != 1)
{
$sql_2 = "select * from test where oid = $last_oid; <<<これが抜けてました。
で、103行目は上記のsql_2のフレーズでした
結果を表示するテーブル作成
}
else
{
エラー表示
}
0170名無しさん@お腹いっぱい。
NGNG0171名無しさん@お腹いっぱい。
NGNG0172cookie
NGNG0173153
NGNGご指摘ありがとうございます。
その場合、今登録された主キーのIDはどのようにして特定すればいい
のでしょうか?
0174電動ナナシ
NGNGというか、主キーが意味はわかっていないのかな・・・。
テーブル中のレコードを一意に識別する ID に相当する列のことだよ。
例えば、人事テーブルがあって、そのテーブルが
(従業員ID, 氏名, 住所, 連絡先)
という風になっており、同姓同名の人を区別するために従業員 ID を使って
識別しているなら、従業員 ID が主キーになる。
普通主キーとなる列に対しては、重複する列の挿入を禁止するために
Primary Key 制約か Unique 制約を定義するけど、その辺ちゃんとやってる?
これは PHP とか PostgreSQL とかいう以前の、データベース一般の設計の
お話だよ?
0175電動ナナシ
NGNGおおっと、ID も Primary Key はあるって >>168 に書いてあるね。
勘違いしていた。ごめんなさい。
なるほどね、INSERT した直後に、自動的に割り当てられる ID をどうやって
特定するかって質問なのね。
これは先の人が書いているように oid を取得して特定するしかないんじゃないかな。
それ以外の列って重複する可能性があるから当てにならないしね。
ちなみに自分は自動連番はやってない。登録フォームを表示するときに
squence から番号を取得して、その番号をフォームに保持させておく。
そうすれば、POST された内容に ID が入っているのでそれをキーに参照
できるようになる。
これの欠点は、番号に欠番が生じるということ。だけどそれがそんなに気に
するほどのことかなあ。
0176名無しさん@お腹いっぱい。
NGNGselect currval() するのもよし、直接使うのもよし。
0177名無しさん@お腹いっぱい。
NGNGNO!
同じスクリプト内であっても、別なプロセスがINSERTしてしまえば
CURRVALの内容は変わってしまう。初心者にありがちなミス。
正解は電動ナナシ氏指摘の通りOIDの取得。
0178名無しさん@お腹いっぱい。
NGNGほんとかな。begin, end で囲っているのに?
0179176
NGNG>CURRVALの内容は変わってしまう。初心者にありがちなミス。
同じセッション内なのに、currval の値は変わるのですか?
last_value の値は保証されないようですけどね。どうか教えてください。
なんせ、初心者 なもので。
0180名無しさん@お腹いっぱい。
NGNG0181名無しさん@お腹いっぱい。
NGNG>last_value の値は保証されないようですけどね。どうか教えてください。
やってみりゃいいじゃん。
0182名無しさん@お腹いっぱい。
NGNGファイル名がpostgresql-7.1.tar.gzになってる。
0183176
NGNG変わらないよ。要はそれを言いたい。
0184176
NGNGわたしの実験ミスも考えられるし、想定外もあるし、
特定の環境というケースもあるので、変わるケースがあるなら
教えて欲しいのですよ。
0185名無しさん@お腹いっぱい。
NGNG話の流れと発言者が何人いるかよくわかりませんが、
>>178でいきなり
>ほんとかな。begin, end で囲っているのに?
という前提条件が登場します。
これが178氏と他の人の差じゃないかな?
>同じセッション内なのに、currval の値は変わるのですか?
という問いには、
* 同一トランザクション内であれば変わらない、が正解。
* begin, endでくくっていない1DML1トランザクションで、currval()を使うのは
誤り。他のプロセス(トランザクションで)値が変わっている可能性がある。
ということでよいでしょうか?>All
0186185
NGNG* begin, endでくくっていない1DML1トランザクションで、currval()を使うのは
誤り。他のプロセス(トランザクションで)値が変わっている可能性がある。
これは誤り。1DML1トランザクションでも、currval()は他のプロセス
(トランザクション)にかかわらず、普遍ですね。
セッション内で一貫性があるようです。
鬱氏。
0187名無しさん@お腹いっぱい。
NGNG0188名無しさん@お腹いっぱい。
NGNG# RDBMSについてしゃべる場所ってどこかないのかな?
0189名無しさん@お腹いっぱい。
NGNG「シーラカンス本」
「マンモス本」
を前提に語るのはやめて欲しいなー。
あ、俺は両方持ってるんだけど。
前者はバージョンが古いし、後者はちょっとアレだし・・・。
今一、人に薦めづらいんだよね、この本って。
0190名無しさん
NGNGinsertで失敗してもカウントが1上がってしまうのですが
これはしょうがないことなのでしょうか?
0191名無しさん@お腹いっぱい。
NGNG0192名無しさん@お腹いっぱい。
NGNG技術系ってそうなのかなぁ。妙に偉そうだったりするの
0193名無しさん@お腹いっぱい。
NGNG0194名無しさん研究所
NGNG激しく同意。うかつに質問なんてできないっしょ。
だから意地になってマニュアル+マンモス本+過去ログで
自分で解決してる。恐ろしく効率悪いけど・・・
# 聞くは一時の恥、聞かぬは一生の恥 とも言いますが・・・
0195名無しさん@お腹いっぱい。
NGNGそう。ネット上じゃ逆だねぇ。。
0196名無しさん@お腹いっぱい。
NGNGトランザクションを入れてみては・・
0197名無しさん@お腹いっぱい。
NGNG環境の違いとかはあるのでしょうか?
あと、お勧めのOSは何ですか?
0198名無しさん@お腹いっぱい。
NGNGうーん、デフォルトの文字コードが違うとか、使えるシステムコールやライブラリ
のPHPのラッパ関数が違うとか、かな?
OSは、Linux系をお勧めします。
0199名無しさん@お腹いっぱい。
NGNG>>196
トランザクションをアボートしても、serial型の場合、
インクリメントされちゃった値はもどんないよ〜。
って、どっかのスレでも話題になってなかった?
0200153
2001/04/21(土) 16:07ID:2SRwUN3cたった今insertで登録したデータをselectで引っ張り出すこと
が出来ました。
ありがとうございます。
0201名無しさん@お腹いっぱい。
2001/04/21(土) 19:35ID:???いや、ほのぼのとして、良いぞ。
0202153です
2001/04/22(日) 10:09ID:GJXSK57Q実はスクリプト自体は皆さんのご指摘を元に作成出来ていたのですが、
ずっとエラーが出続けてました。
で、oid=$last_oidの部分が多分問題なのかと思って、ここを色々
いじくっていたんです。
解決出来たのは、もう一度スクリプトをじっくりと眺めていて、「"」
と「'」が2か所抜けておりました・・・
0203名無しさん@お腹いっぱい
2001/05/05(土) 16:54ID:ejxtLiFAPHPで外部からきたデータに大して、そのままSQL文をつくると、例えば、$a_post_datumが"これは'クォーテーション'です"みたいなので、
pg_exec($conn, "select col from a_table where col2 = '$a_post_datum'");
みたいにすると文字列展開で
"select col from a_table where col2 = 'これは'クォーテーション'です'"
みたいになって、SQL文が成立しなくなるんだけど、みなさん、こういうのにはどう対処しているんでしょうか?
0204名無しさん@お腹いっぱい。
2001/05/05(土) 17:35ID:???0205203
2001/05/05(土) 18:30ID:ejxtLiFA%と_は?
0206名無しさん@お腹いっぱい。
2001/05/05(土) 20:35ID:???0207203
2001/05/06(日) 16:11ID:kun4pZhs0208名無しさん@お腹いっぱい。
2001/05/06(日) 18:36ID:???シングルクォートのときはシングルクォートの前に入れるだけで良かったと思うけど。
0209名無しさん@お腹いっぱい。
2001/05/07(月) 20:18ID:???これさえいらなければなーとつくづく思うんだがね > PostgreSQL
■ このスレッドは過去ログ倉庫に格納されています