Postgresql

INSERT INTO table FROM SELECT * with nextval() 規範

  • May 9, 2017

我需要複製同一張表中的記錄,只更改一個欄位**。**我的表具有預設生成的序列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並且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;

引用自:https://dba.stackexchange.com/questions/173103