レコードをコピーする必要がありますwithin 1つのフィールドのみを変更する同じテーブル。テーブルにデフォルトで生成されたシーケンス_entry_id_seq
_がありますが、id
列がSERIALであるかどうかはわかりません(確認方法は?)。
_\d tab
_はこれだけを返します
_ Column | Type | Modifiers
-----------------+--------------------------------+------------------------
id | integer | not null
...
Indexes:
"tab_entry_pkey" PRIMARY KEY, btree (id)
_
だから問題は:簡単な方法でレコードをコピーしようとすると:
_insert into tab_entry select * from tab_entry where id = 3052;
_
エラーが発生します
_ERROR: duplicate key value violates unique constraint "tab_entry_pkey"
DETAIL: Key (id)=(3052) already exists.
_
デフォルトのシーケンスでは、デフォルトで次の値は生成されません。完全なテーブル指定(FROM tab(col1, col2, col3, ..., col N)
)なしで単一フィールドを挿入および変更できる簡潔な構文はありますか?
テーブルには多くのフィールドがあるので、コードの読みやすさに影響するため、すべてを記述したくありません。このようなものが欲しいのですが、この構文は機能しません
_insert into tab_entry(id, *) select nextval('seq'), * from tab_entry where id = 3052;
_
そして、このSELECT nextval('seq')
アプローチは、一度に複数のレコードがある場合に機能しますか?
PsqlとPostgresのバージョンは9.6.2です。
コメントで述べたように、そのようなタスクには特別な構文はありません。
関数の組み合わせを使用できます to_json(b)
、json(b)_set
and json(b)_populate_record
:
--drop table if exists t;
create table t(i serial primary key, x int, y text, z timestamp);
insert into t values(default, 1, 'a', now()),(default, 2, 'b', now());
insert into t
select n.*
from t, jsonb_populate_record(
null::t,
jsonb_set(
to_jsonb(t.*),
array['i'],
to_jsonb(nextval('t_i_seq')))) as n;
select * from t;
しかし、すべての列を列挙するだけではそれほど単純ではないと思います。常にこの比較的単純なクエリを使用して、テーブルの列リストを取得できます。
select string_agg(attname,',' order by attnum)
from pg_attribute
where attrelid = 'public.t'::regclass and attnum > 0;