2008-09-24 10 views
19

¿Es posible cambiar el orden natural de las columnas en Postgres 8.1?¿Es posible cambiar el orden natural de las columnas en Postgres?

Yo sé que usted no debe confiar en orden de columnas - no es esencial a lo que estoy haciendo - Yo sólo necesito hacer algunas cosas autogenerado salir de una manera que es más agradable, por lo que el orden de campo coincide desde pgadmin hasta el extremo posterior.

Respuesta

18

En realidad, puede cambiar el orden de las columnas, pero no lo recomendaría, y debe tener mucho cuidado si decide hacerlo.

por ejemplo.

 
# CREATE TABLE test (a int, b int, c int); 
# INSERT INTO test VALUES (1,2,3); 
# SELECT * FROM test; 
a | b | c 
---+---+--- 
1 | 2 | 3 
(1 row) 

Ahora, para el poco complicado, tiene que conectarse a la base de datos utilizando el usuario postgres para que pueda modificar las tablas del sistema.

 
# SELECT relname, relfilenode FROM pg_class WHERE relname='test'; 
relname | relfilenode 
---------+------------- 
test_t |  27666 
(1 row) 

# SELECT attrelid, attname, attnum FROM pg_attribute WHERE attrelid=27666; 
attrelid | attname | attnum 
----------+----------+-------- 
    27666 | tableoid |  -7 
    27666 | cmax  |  -6 
    27666 | xmax  |  -5 
    27666 | cmin  |  -4 
    27666 | xmin  |  -3 
    27666 | ctid  |  -1 
    27666 | b  |  1 
    27666 | a  |  2 
    27666 | c  |  3 
(9 rows) 

attnum es una columna única, por lo que es necesario utilizar un valor temporal cuando se está modificando los números de columna como tal:

 
# UPDATE pg_attribute SET attnum=4 WHERE attname='a' AND attrelid=27666; 
UPDATE 1 
# UPDATE pg_attribute SET attnum=1 WHERE attname='b' AND attrelid=27666; 
UPDATE 1 
# UPDATE pg_attribute SET attnum=2 WHERE attname='a' AND attrelid=27666; 
UPDATE 1 

# SELECT * FROM test; 
b | a | c 
---+---+--- 
1 | 2 | 3 
(1 row) 

Una vez más, porque este está jugando con las tablas del sistema de base de datos , ten mucho cuidado si sientes que realmente necesitas hacer esto.

Este funcionamiento es el de Postgres 8.3, con las versiones anteriores, su kilometraje puede variar.

+4

Esto es muy complicado, varios objetos del sistema se refieren a un número de columna. Cuando voltea las columnas 2 y 3, tendrá problemas cuando un objeto necesita algo de la columna 2. Esto ahora es nr. 3 y su base de datos ahora está dañado. Eche un vistazo a pg_constraint, esto puede ser un protector de base de datos. –

+3

De esta manera pierde todos los datos en su pestaña les. –

+5

Además de no ser compatible, esta técnica intercambia los nombres de columna sin respetar sus contenidos, lo cual (a pesar de que la respuesta sea aceptada) no es lo que la pregunta está haciendo. Y si lo estaba pidiendo, se debe usar 'ALTER TABLE ... RENAME COLUMN ...' en su lugar, ya que logra el mismo resultado pero de manera confiable. –

0

Lamentablemente, no, no lo es. El orden de la columna depende por completo de Postgres.

1

Especificar el orden de las columnas en la consulta es la única manera confiable (y segura) de. Dicho esto, normalmente puede obtener un pedido diferente alterando la tabla como se muestra en el ejemplo a continuación, ya que las columnas normalmente (no se garantiza que lo sean) se devuelven en el orden en que se agregaron a la tabla.

postgres=# create table a(a int, b int, c int); 
CREATE TABLE 
postgres=# insert into a values (1,2,3); 
INSERT 0 1 
postgres=# select * from a; 
a | b | c 
---+---+--- 
1 | 2 | 3 
(1 row) 

postgres=# alter table a add column a2 int; 
ALTER TABLE 
postgres=# select * from a; 
a | b | c | a2 
---+---+---+---- 
1 | 2 | 3 | 
(1 row) 

postgres=# update a set a2 = a; 
UPDATE 1 
postgres=# alter table a drop column a; 
ALTER TABLE 
postgres=# alter table a rename column a2 to a; 
ALTER TABLE 
postgres=# select * from a; 
b | c | a 
---+---+--- 
2 | 3 | 1 
(1 row) 

postgres=# 
+0

No estoy escribiendo una consulta. Estoy usando un producto que autogenera consultas, formularios y demás. Puedo editarlo después de que se haya generado, pero prefiero poder regenerarlo y no tener que volver a editarlo. – rjmunro

+0

Luego pregunte al proveedor del producto sobre la forma de especificar el orden de las columnas (o solicite que lo agreguen como característica) –

+0

Los desarrolladores de IIRC Postgresql no desean agregar esta función :( – grom

3

Como las otras respuestas mencionadas, no puede cambiar el orden de las columnas, eso depende de postgres. Puede (¡y debería!) Resolver su problema con una vista. A los efectos de su consulta de informes, se verá como una tabla. Algo así como:

create view my_view as 
    select * from my_table 
    order by some_col; 
+2

Eso no cambia el orden de las columnas, eso está cambiando el orden de los datos basado en una columna – rjmunro

12

Si su base de datos no es muy grande y se lo puede permitir un tiempo de inactividad después usted puede:

  1. acceso de escritura Desactivar para la base de datos
    esto es esencial, ya que de lo contrario cualquier cambio después de a partir del siguiente punto se perderá
  2. pg_dump --create --column-inserts databasename > databasename.pgdump.sql
  3. Editar apropriate CREATE TABLE declaración en Databa sename.pgdump.sql
    Si el archivo es demasiado grande para su editor simplemente dividirlo usando split de comandos, editar, a continuación, montar la espalda usando cat
  4. drop database databasename
    Usted tiene una copia de seguridad reciente, por si acaso, ¿Vos si?
  5. psql --single-transaction -f databasename.pgdump.sql
    Si no se utiliza --single-transaction será muy lenta

Si utilizar los llamados grandes objetos asegurarse de que están incluidos en el vertedero. No estoy seguro de si están por defecto en 8.1.

+0

Esto funciona bastante bien con 9.3. Tenga en cuenta que si desea importar a una nueva base de datos puede cambiar las tres líneas en el archivo de volcado que hacen referencia al nombre de la base de datos. –

+0

funciona bien con 9.6.1 también – docesam

7

me han hecho esa pregunta en pgsql-admin en 2007. Tom Lane, declaró el propio prácticamente inviable para cambiar el orden en los catálogos. Aclaración: .. para usuarios, con las herramientas presentes (sigue siendo cierto para v9.1). No significa que no podría ser implementado. OMI, debería ser.
http://archives.postgresql.org/pgsql-admin/2007-06/msg00037.php

+2

"La idea de permitir el reordenamiento de la posición de la columna no es una a la que los desarrolladores de postgresql están en contra, es más un caso en el que nadie ha dado un paso adelante para hacer el trabajo". cita de http://wiki.postgresql.org/wiki/Alter_column_position En caso de que alguien quiera agregar esa funcionalidad ... los pasos iniciales se han esbozado al final del artículo. –

+2

+1 en eso, aunque todos los que creo lo saben. Según la respuesta de Igor Neyman, algunos parecen no tener una razón para ello. Creo que a menudo hay situaciones en las que esta característica es útil, esp. para personas con OCD en esquema como yo. Como señaló Tom Lane, también necesitaríamos cambiar "vistas, claves externas, índices, valores predeterminados, reglas, etc." y todo lo demás depende de las columnas. Eso en realidad no parece tan inimaginable, incluso solo usando PL/pgSQL. Creo que la mayoría de nosotros tropezamos con este problema y nos sentimos como "si tuviera el tiempo". –

0

Usted puede obtener el ordenamiento columna que desee mediante la creación de una nueva tabla y seleccionar columnas de la mesa de edad en el orden en que desea que presenten:

CREATE TABLE test_new AS SELECT b, c, a FROM test; 
SELECT * from test_new; 
b | c | a 
---+---+--- 
2 | 3 | 1 
(1 row) 

Tenga en cuenta que estos datos copias solamente, no modificadores, restricciones, índices, etc ..

una vez que la nueva tabla se modifica de la manera deseada, deje caer el original y modificar el nombre de la nueva:

BEGIN; 
DROP TABLE test; 
ALTER TABLE test_new RENAME TO test; 
COMMIT; 
0

estoy queriendo lo mismo. Sí, la orden ahora esencial, pero sólo me roza el camino equivocado :)

Lo que estoy haciendo para resolverlo es la siguiente.

Este método será asegurarse de que mantener todos los datos existentes,

  1. crear una nueva versión de la tabla con el pedido que quiero, usando un nombre temporal.
  2. Insertar todos los datos en que la nueva tabla de la existente.
  3. Suelta la tabla anterior.
  4. Cambiar el nombre de la nueva tabla para el "nombre propio" de "nombre temporal".
  5. Vuelva a agregar los índices que tenía anteriormente.
  6. Restablecer secuencia de ID para incrementos de tecla primaria.

actual orden de la tabla:

id, name, email 

1. Crear una nueva versión de la tabla utilizando el orden que quiera, utilizando un nombre temporal.

En este ejemplo, quiero que email sea anterior a name.

CREATE TABLE mytable_tmp 
(
    id SERIAL PRIMARY KEY, 
    email text, 
    name text 
); 

2. Insertar los datos en esa nueva tabla de la existente.

INSERT INTO mytable_tmp --- << new tmp table 
(
    id 
, email 
, name 
) 
SELECT 
    id 
, email 
, name 
FROM mytable; --- << this is the existing table 

3. La caída de la mesa de edad.

DROP TABLE mytable; 

4. Cambiar el nombre de la nueva tabla con el "nombre propio" de "nombre temporal".

ALTER TABLE mytable_tmp RENAME TO mytable; 

5. Vuelva a agregar cualquier índice que tenía anteriormente.

CREATE INDEX ... 

6. secuencia ID Reset durante incrementos de clave primaria.

SELECT setval('public.mytable_id_seq', max(id)) FROM mytable; 
Cuestiones relacionadas