6

私はpostgreSQLを初めて使用するので、コミュニティからのポインタをいただければ幸いです。

継承したばかりのかなり古いサイトのCMSの一部の機能を更新しています。基本的に、データベースに挿入する前に記事のIDが必要です。とにかく、データベースセッション(挿入)が始まる前にシーケンスによって使用される次の値をチェックする方法はありますか?

最初は使用できると思いSELECT max(id) from tbl_nameましたが、IDはシーケンスから自動的にインクリメントされ、記事は削除されることが多いため、シーケンス内の次の値に対して正しいIDが返されないことは明らかです。

記事がまだデータベースになく、データベースセッションが開始されていないため、currval()postgreSQLの機能を使用できないようです。さらに、これを使用するnextval()と、データが挿入される前にシーケンスが自動インクリメントされます(挿入によってシーケンスが自動インクリメントされ、シーケンスが二重にインクリメントされます)。

私が現在それを回避している方法は次のとおりです。

function get_next_id()
{
    $SQL = "select nextval('table_id_seq')";
    $response = $this->db_query($SQL);
    $arr = pg_fetch_array($query_response, NULL, PGSQL_ASSOC);

    $id = (empty($arr['nextval'])) ? 'NULL' : intval($arr['nextval']);
    $new_id = $id-1;
    $SQL = "select setval('table_id_seq', {$new_id})";
    $this->db_query($SQL);

    return $id;
}

SELECT nextval('table_id_seq')シーケンス内の次のIDを取得するために使用します。これによりシーケンスがインクリメントされるので、すぐにシーケンスをSELECT setval('table_id_seq',$id)元の値に戻すために使用します。このように、ユーザーがデータを送信し、コードが最終的にINSERTステートメントにヒットすると、自動インクリメントされ、挿入前と挿入後のIDは同一になります。

これは私にとってはうまくいきますが、私はpostgreSQLにあまり熱心ではなく、それが将来的に問題を引き起こす可能性があるのか​​、それとも彼らがより良い方法ではないのか疑問に思っています。自動インクリメントせずにシーケンスの次の値をチェックする方法はありませんか?

それが役立つ場合は、postgresql7.2を使用しています

4

2 に答える 2

4

皆さん-レコードを挿入するにIDを取得する理由があります。たとえば、別のフィールドに挿入されるテキストの一部としてIDを格納するアプリケーションがあります。これを行うには2つの方法しかありません。

1)メソッドに関係なく、挿入する前にIDを取得してINSERTステートメントに含めます
。2)INSERT、IDを取得します(これも、(SELECT...またはINSERT... RETURNING id;)からの方法に関係なく)、更新します。 IDを含むレコードのテキストフィールド

コメントと回答の多くは、OPが何か間違ったことをしていると想定していました...それは...間違っています。OPは、「基本的に、データベースに挿入する前に記事のIDが必要です」と明確に述べています。OPがこれを望んでいる/必要としている理由は重要ではありません-質問に答えるだけです。

私のソリューションは、IDを前もって取得することを選択しました。したがって、必要な結果を達成するために、必要に応じてnextval()とsetval()を実行します。

于 2013-11-08T18:04:19.103 に答える
2

免責事項:私はそれを使用したことがないので、7.2についてはよくわかりません。

どうやらあなたのID列はシーケンスからデフォルト値を取得するように定義されているようです(おそらくそれserialが7.xで利用可能かどうかはわかりませんがとして定義されているためです)。

nextval()デフォルトを削除してもシーケンスを保持する場合は、新しい行を挿入する前にを使用して次のIDを取得できます。

列のデフォルト値を削除するには、挿入時に常にIDを指定する必要があります(シーケンスからIDを取得することにより)。とにかくそうしているのなら、問題はありません。両方のシナリオに対応する場合は、ID列に値があるかどうかを確認するbefore insertトリガーを作成します(7.xには値がありますか?)。そうでない場合は、シーケンスから新しい値を取得します。そうでない場合はそのままにします。

しかし本当の問題は、挿入する前になぜIDが必要なのかということです。行をサーバーに送信し、次を呼び出すことで生成されたIDを取得できます。curval()

しかし、繰り返しになりますが、Postgresの最新バージョンにアップグレードするには、実際に(つまり、実際に)顧客と話し合う必要があります。

于 2012-06-13T08:02:24.303 に答える