6

編集: ダニエルとデニスの両方に感謝します。問題は現在解決されており、彼らが巧妙に指摘したように、この場合の問題はプログラマーでした (具体的には最後まで考えていませんでした)。両方を答えとして受け入れることができればいいのにと思います。

注: 私が postgresql の初心者であると言うのは、初心者を侮辱することです!

データ ストレージに PostgreSQL データベースを利用する Web アプリを作成しています。これまでの作業で、検索、削除、挿入、更新のいずれであっても、クエリを作成し、クエリから結果を取得するための構文を十分に理解できました。しかし、私は 1 つの困惑に遭遇しました。

SQL インジェクションの問題を回避するには、pg_prepare()/pg_execute()またはの使用をpg_query_paramsお勧めします。私はpg_prepare()/pg_execute()他のものよりも多くを使用しています。ただし、各クエリは 4 ステップのプロセスです。

  1. クエリ文字列自体を準備し、
  2. データベースでクエリを準備する (pg_prepare を使用)
  3. クエリを実行します (pg_execute)
  4. 返されたデータを処理/操作します。

これは PHP スクリプトであるため、準備されたクエリはスクリプトの終了時に自動的に割り当て解除されないため、次のような呼び出しを介して手動で行う必要があります。

pg_query($dbconn, "DEALLOCATE 'query_name';")

ただし、DEALLOCATESQL コマンドは成功または失敗に関する有用な情報を返さないため、DEALLOCATE命令の結果を判断しようとすると、次のことを判断するのが面倒になります。

  1. クエリは成功し、割り当て解除も成功しました
  2. クエリは成功し、割り当て解除は失敗しました
  3. クエリが失敗し、割り当て解除も失敗しました
  4. クエリは失敗し、割り当て解除は成功しました (これが起こるとは思えません)

私の質問は2つあります」

  1. 割り当て解除が成功したかどうかをどのように判断できますか (割り当て解除されたクエリに関するサーバーへの繰り返しのクエリを除く)。
  2. クエリのどの部分が失敗したか (失敗した場合)、割り当て解除、またはクエリ自体の送信を判断する簡単な方法はありますか?

この質問は部分的な解決策を提供しますが、エラーのソースを見つけるのには役立ちません. PHP/PostgreSQL: 準備済みステートメントが既に存在するかどうかを確認します

4

2 に答える 2

9

pg_queryステートメントの割り当てを解除すると、「ユーティリティステートメント」の場合と同様に、の戻り値が成功したかどうかを示します。失敗した場合は false を返す必要があります。例えば:

 if (!pg_query($cnx, "deallocate foobar")) {
   echo "Error deallocate: " . pg_last_error($cnx);
 }
 else {
  echo "deallocate successful";
 }

これは次のように表示されます。

エラー割り当て解除: エラー: 準備済みステートメント "foobar" が存在しません

割り当てを解除するステートメント名は、文字列リテラルではなく識別子であるため、一重引用符で囲まないでください。問題のある文字のために囲む必要がある場合は、pg_escape_identifier(php >=5.4.4)で行うことができます。

セッションをクリーンアップするために、準備されたステートメントを反復処理して 1 つずつ割り当てを解除する必要さえありませDEALLOCATE ALLpg_query

1 つのクエリでより多くのクリーンアップを行う別のステートメントもあります。 DISCARD ALL

また、準備されたステートメントは親セッションに対してローカルであり、それとともに終了するため、スクリプトが実際に postgres から切断された場合でも、これは必要ありません。

明示的なクリーンアップは、スクリプト間の接続の再利用を使用する場合に必要です。PHP による永続的な接続 ( pg_pconnect)、またはpgBouncerのような接続プーラー(構成によってはプーラー自体が呼び出すDISCARD ALL場合があります) のいずれかです。

于 2013-11-09T13:24:57.117 に答える