web-dev-qa-db-ja.com

INSERT ... RETURNINGの戻り値を別のINSERTで使用できますか?

このようなことは可能ですか?

INSERT INTO Table2 (val)
VALUES ((INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id));

戻り値を値として使用して、最初のテーブルへの参照を含む2番目のテーブルに行を挿入するようなものですか?

65
Eike Cochu

Postgres 9.1から開始できます:

with rows as (
INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id
)
INSERT INTO Table2 (val)
SELECT id
FROM rows

一方、IDのみに関心がある場合は、トリガーを使用して行うことができます。

create function t1_ins_into_t2()
  returns trigger
as $$
begin
  insert into table2 (val) values (new.id);
  return new;
end;
$$ language plpgsql;

create trigger t1_ins_into_t2
  after insert on table1
for each row
execute procedure t1_ins_into_t2();
79

この状況のベストプラクティス。つかいます - RETURNING … INTO

INSERT INTO teams VALUES (...) RETURNING id INTO last_id;
46
Alexandre Assi

Denis de Bernardyの回答に沿って。

その後もidを返したい場合、Table2により多くのものを挿入したい場合:

with rows as (
INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id
)
INSERT INTO Table2 (val, val2, val3)
SELECT id, 'val2value', 'val3value'
FROM rows
RETURNING val
8
Bhindi

lastval() 関数を使用できます。

シーケンスに対してnextvalで最後に取得された戻り値

だからこのようなもの:

INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val)  VALUES (lastval());

これは、INSERTの間の他のシーケンス(現在のセッション内)でnextval()を呼び出さない限り、正常に機能します。

Denis 以下に注意し、上記で警告したように、lastval()を使用すると、INSERTの間にnextval()を使用して別のシーケンスにアクセスした場合に問題が発生します。これは、シーケンスのnextval()を手動で呼び出したTable1にINSERTトリガーが存在する場合、またはより多くの場合、 SERIALまたはBIGSERIAL 主キー。本当に妄想的になりたい場合(良いこと、theyは本当にあなたを手に入れたいですか)、 currval() ただし、関連するシーケンスの名前を知る必要があります。

INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val)  VALUES (currval('Table1_id_seq'::regclass));

自動的に生成されるシーケンスは通常t_c_seqという名前です。ここで、tはテーブル名、cは列名ですが、psqlと言って:

=> \d table_name;

次に、問題の列のデフォルト値を確認します。次に例を示します。

id | integer | not null default nextval('people_id_seq'::regclass)

参考:lastval()は、多かれ少なかれ、MySQLのPostgreSQLバージョン LAST_INSERT_ID です。多くの人がPostgreSQLよりもMySQLに精通しているので、lastval()を馴染みのあるものにリンクすると物事が明確になる可能性があるため、これについてのみ言及します。

7
mu is too short
DO $$
DECLARE tableId integer;
BEGIN
  INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id INTO tableId;
  INSERT INTO Table2 (val) VALUES (tableId);
END $$;

Psql(10.3、サーバー9.6.8)でテスト済み

3
Anders B

table_ex

id default nextval( 'table_id_seq' :: regclass)、

camp1 varchar

camp2 varchar

INSERT INTO table_ex(camp1,camp2) VALUES ('xxx','123') RETURNING id 
0
kemado77