如何使用postgres在表中的第二或第三列之后的表中添加新的列?
如何使用postgres在表中的第二或第三列之后的表中添加新的列?
我的代码如下所示
ALTER TABLE n_domains ADD COLUMN contract_nr int after owner_id
不,没有直接的方法来做到这一点。 这是有原因的 – 每个查询都应该列出所需的所有字段,而不pipe他们需要什么顺序(和格式等),从而使得一个表中列的顺序不重要。
如果你真的需要这样做,我可以想一个解决方法:
- 转储并保存有问题的表的描述(使用
pg_dump --schema-only --table=<schema.table> ...
) - 将所需的列添加到保存的定义中
- 重命名已保存的定义中的表,以免试图创build它时与旧表的名称冲突
- 使用此定义创build新表
- 使用INSERT INTO
<new_table>
SELECT field1,field2,<default_for_new_field>
,field3,… FROM<old_table>
填充新表格中的数据。 - 重命名旧表
- 将新表重命名为原始名称
- 最后放下旧的,改名后的桌子,确保一切正常
列的顺序并不无关紧要,将固定宽度的列放在表格的前面可以优化数据的存储布局,还可以使应用程序代码之外的数据更容易处理。
PostgreSQL不支持更改列顺序(请参阅更改 PostgreSQL wiki上的列位置 ); 如果表格相对孤立,则最好的办法是重新创build表格:
CREATE TABLE foobar_new ( ... ); INSERT INTO foobar_new SELECT ... FROM foobar; DROP TABLE foobar CASCADE; ALTER TABLE foobar_new RENAME TO foobar;
如果您有很多针对表定义的视图或约束,您可以在新列之后重新添加所有列并删除原始列(有关示例,请参阅PostgreSQL wiki)。
上面的解决scheme几乎可以奏效,但是如果序号是closures的(如果重新sorting的序号使得不兼容的types匹配,那么将会做错误的事情)。 试一试:
CREATE TABLE test1 (one varchar, two varchar, three varchar); CREATE TABLE test2 (three varchar, two varchar, one varchar); INSERT INTO test1 (one, two, three) VALUES ('one', 'two', 'three'); INSERT INTO test2 SELECT * FROM test1; SELECT * FROM test2;
结果显示问题:
testdb=> select * from test2; three | two | one -------+-----+------- one | two | three (1 row)
您可以通过指定插入中的列名来弥补这一点:
INSERT INTO test2 (one, two, three) SELECT * FROM test1;
这给了你真正想要的东西:
testdb=> select * from test2; three | two | one -------+-----+----- three | two | one (1 row)
问题出在你有遗传不这样做的时候,正如我在我对peufeu答复的评论中所指出的那样。
更新:在我看来,通过在SELECT子句中指定列名,您可以对INSERT子句中的列名执行相同的操作。 你只需要重新sorting它们以匹配目标表中的序号:
INSERT INTO test2 SELECT three, two, one FROM test1;
你当然可以做得很明确:
INSERT INTO test2 (one, two, three) SELECT one, two, three FROM test1;
这给你与上面相同的结果,列值恰当匹配。
@ Milen A. Radev
具有设置的列顺序的不相关需求并不总是由拉取它们的查询定义的。 在来自pg_fetch_row
的值中不包含关联的列名称,因此需要由SQL语句定义列。
一个简单的select * from
将需要天生的表结构知识,并且如果列的顺序改变,有时会引起问题。
使用pg_fetch_assoc
是一种更可靠的方法,因为您可以引用列名称,因此可以使用简单的select * from
。
关系数据库中列的顺序是完全不相关的
是。
例如,如果你使用Python,你会这样做:
cursor.execute( "SELECT id, name FROM users" ) for id, name in cursor: print id, name
或者你会这样做:
cursor.execute( "SELECT * FROM users" ) for row in cursor: print row['id'], row['name']
但是没有一个理智的人会使用这样的定位结果:
cursor.execute( "SELECT * FROM users" ) for id, name in cursor: print id, name