35

Codeigniter Web サイトに PostgreSQL を使用しています。追加、編集、および削除操作に食料品のクラッドを使用しています。編集または追加中に、コンテンツの ID に基づいてアップロードされたファイルの名前を動的に変更したいと考えています。私は食料品のcrudのcallback_after_upload機能を使ってこれを行うことができます。

新しいコンテンツを追加するときに、コンテンツの次の ID が必要です。関数を使用しようとしましnextval()たが、シーケンスがインクリメントされます。関数を使用せずにシーケンスの最後の値を取得するにはどうすればよいnextval()ですか?

または、これを行う簡単な方法はありますか?

4

7 に答える 7

41

RETURNING

これは、データベースへの1 回の往復で可能です。

INSERT INTO tbl(filename)
VALUES ('my_filename')
RETURNING tbl_id;

tbl_id通常、serialまたはIDENTITY(Postgres 10 以降) column になります詳しくはマニュアルをご覧ください。

値を明示的にフェッチする

filename(冗長に)含める必要がある場合tbl_idでも、単一のクエリを使用できます。

またはlastval()より具体的なcurrval():

INSERT INTO tbl (filename)
VALUES ('my_filename' || currval('tbl_tbl_id_seq')   -- or lastval()
RETURNING tbl_id;

見る:

プロセスで複数のシーケンスが進行する可能性がある場合 (トリガーやその他の副作用によっても)、確実な方法は を使用することcurrval('tbl_tbl_id_seq')です。

配列名

この例の文字列リテラルは、シーケンスの 実際の'tbl_tbl_id_seq'名前であると想定され、にキャストされます。現在の にその名前のシーケンスが見つからない場合、例外が発生します。regclasssearch_path

tbl_tbl_id_seqtblは、シリアル列を持つテーブルに対して自動的に生成されるデフォルトですtbl_id。しかし、保証はありません。列のデフォルトは、そのように定義されている場合、任意のシーケンスから値を取得できます。また、テーブルの作成時にデフォルト名が使用される場合、Postgres は単純なアルゴリズムに従って次の自由な名前を選択します。

列のシーケンスの名前がわからない場合はserial、専用の関数を使用してpg_get_serial_sequence()ください。その場で行うことができます:

INSERT INTO tbl (filename)
VALUES ('my_filename' || currval(pg_get_serial_sequence('tbl', 'tbl_id'))
RETURNING tbl_id;

ここでdb<>fiddle
古いsqlfiddle

于 2012-11-15T08:59:58.750 に答える
28

関数を使用して、以前に取得したシーケンスの値にアクセスしcurrval()ます。

ただし、それより前nextval()に呼び出された場合にのみ値を返します。

実際に取得することなく、シーケンスの次の値を「覗く」方法は絶対にありません。

しかし、あなたの質問は不明確です。挿入を行う前に呼び出すとnextval()、挿入でその値を使用できます。または、さらに良いことcurrval()に、insert ステートメントで使用します。

select nextval('my_sequence') ...

... do some stuff with the obtained value

insert into my_table(id, filename)
values (currval('my_sequence'), 'some_valid_filename');
于 2012-11-15T08:15:58.277 に答える
3

セッションに参加していない場合は、 nextval('you_sequence_name') だけで問題ありません。

于 2016-07-19T19:17:48.580 に答える
0

たとえこれがどうにかできたとしても、別のレコードで使用されるシーケンスを取得する可能性があるため、それはひどい考えです!

はるかに良いアイデアは、レコードを保存してからシーケンスを取得することです。

于 2012-11-15T08:18:56.570 に答える
0

私はこれを試しましたが、完全に機能します

@Entity
public class Shipwreck {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
  @Basic(optional = false)
  @SequenceGenerator(name = "seq", sequenceName = "shipwreck_seq", allocationSize = 1)
  Long id;

....

CREATE SEQUENCE public.shipwreck_seq
    INCREMENT 1
    START 110
    MINVALUE 1
    MAXVALUE 9223372036854775807
    CACHE 1;
于 2017-08-14T14:24:56.633 に答える