如何使用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