我试图建立临时表的单元测试的目的。 到目前为止,我设法创建一个临时表,复制现有的表的结构:
CREATE TEMP TABLE t_mytable (LIKE mytable INCLUDING DEFAULTS);
但这种缺乏从原始表中的数据。 我可以通过使用数据复制到临时表CREATE TABLE AS
语句来代替:
CREATE TEMP TABLE t_mytable AS SELECT * FROM mytable;
但随后的结构t_mytable
不会完全相同,例如列大小和缺省值是不同的。 是否有一个单独的语句,其副本的一切吗?
使用第一个查询的另一个问题LIKE
是键列仍引用SEQUENCE
原始表,从而增加它插入。 有一个简单的方法来与它自己的序列创建新表,否则我将不得不成立了由手工一个新的序列?
Postgres的10或更高版本
Postgres的10分介绍IDENTITY
列符合SQL标准(含有少量扩展)。 你的表的ID列看起来是这样的:
id integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
语法的说明书中无。
使用替代传统的这个serial
柱与序列避免你的问题。 IDENTITY
列自动使用独占的,专用的序列,即使在说明书中被复制与LIKE
。 手动:
如果复制列定义的任何标识规范将只能拷贝INCLUDING IDENTITY
指定的。 一种新的序列为新表的每一标识列,从与旧表相关联的序列分开的创建。
和:
INCLUDING ALL
被的缩写形式INCLUDING DEFAULTS INCLUDING IDENTITY INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING STORAGE INCLUDING COMMENTS
。
该解决方案现在更简单:
CREATE TEMP TABLE t_mytable (LIKE mytable INCLUDING ALL);
INSERT INTO t_mytable TABLE mytable;
SELECT setval(pg_get_serial_sequence('t_mytable', 'id'), max(id)) FROM tbl;
作为证明,你仍然可以使用setval()
来设置序列当前值。 单个SELECT
的伎俩。 使用pg_get_serial_sequence()
来获取序列的名称。
分贝<>小提琴这里
有关:
- 如何重置Postgres的主键序列时,它属于不同步?
- 是否有SELECT *快捷方式的?
- 创建一个PostgreSQL序列的字段(这不是记录的ID)
原来(旧)答案
您可以从数据库转储或类似的GUI创建脚本的pgAdmin (其中逆向工程数据库对象创建脚本),创建一个完全相同的副本(有独立的序列为serial
列),然后运行:
INSERT INTO new_tbl
SELECT * FROM old_tbl;
副本不能100%相同的,如果两个表驻留在相同的模式。 显然,表名必须是不同的。 指数名称将发生冲突了。 从同一个序列获取序列号可能不会成为您的最佳利益,无论是。 所以,你必须(至少)调整的名称。
在不同的模式将复制避免了所有这些冲突。 当你从一个普通的表像你展示了创建临时表,既然临时表驻留在自己临时的模式是自动的情况下。
或者在看旧金山的回答对DDL代码直接复制。
我使用下面的代码来做到这一点:
CREATE TABLE t_mytable (LIKE mytable INCLUDING ALL);
ALTER TABLE t_mytable ALTER id DROP DEFAULT;
CREATE SEQUENCE t_mytable_id_seq;
INSERT INTO t_mytable SELECT * FROM mytable;
SELECT setval('t_mytable_id_seq', (SELECT max(id) FROM t_mytable), true);
ALTER TABLE t_mytable ALTER id SET DEFAULT nextval('t_my_table_id_seq');
ALTER SEQUENCE t_mytable_id_seq OWNED BY t_mytable.id;