2009-02-23 69 views
9

Al agregar una columna a una tabla existente, Oracle siempre coloca la columna al final de la tabla. ¿Es posible decirle a Oracle dónde debería aparecer en la tabla? ¿Si es así, cómo?En Oracle, ¿es posible "insertar" una columna en una tabla?

+2

"¿Por qué la orden es importante?" por supuesto, le importa a alguien que intenta leer la cosa. El orden lo hace más comprensible. – tdugan

+0

@tdugan - alguien que intenta leer la cosa puede ordenar las columnas de la forma que quiera. –

+0

@JeffreyKemp: Sí, pueden pedirlos cada vez que lo miran, una y otra vez ... – maaartinus

Respuesta

1

No lo creo - SQL Server tampoco permite esto. El método siempre tengo que usar es:

  1. Crear nueva tabla que se ve a la derecha (incluyendo columna adicional
  2. iniciar la transacción
  3. seleccionar todos los datos de la tabla de edad en la nueva tabla uno
  4. gota de edad
  5. Cambiar el nombre de la nueva tabla
  6. confirmar la transacción.
No

exa Muy bonita, pero hace el trabajo.

+1

SQL Server le permitirá colocar una columna en una tabla donde desee cuando use el Diseñador de tablas. Esto puede hacerse incluso si ya hay datos y filas en la tabla actual (siempre y cuando tenga la columna establecida en Nullable o establezca un valor predeterminado) – TheTXI

+0

Lo suficientemente, pero en el back-end, ejecuta este script exacto. Incluso si agrega una columna al final de una tabla, lo hace, razón por la cual las modificaciones de la tabla a través del diseñador pueden tardar años en ejecutarse realmente. – SqlRyan

+1

Los pasos 2. y 6. son redundantes. Todas las sentencias DDL que alteran el esquema fuerzan una nueva transacción implícita. No puede tener cambios sobresalientes de DML cuando cambia la estructura. – Khb

2

lo que hago normalmente es:

  1. renombrar la tabla de edad.
  2. Crea la nueva tabla con columnas en el orden correcto.
  3. Crea las restricciones para esa nueva tabla.
  4. Rellenar con datos: inserta en nueva_tabla selecciona * de la tabla renombrada.
2

No creo que esto se pueda hacer sin guardar los datos en una tabla temporal, soltar la tabla y volver a crearla. Por otro lado, realmente no debería importar dónde está la columna. Siempre que especifique las columnas que está recuperando en su declaración de selección, puede ordenarlas como desee.

0

No, no es posible a través de una declaración "ALTER TABLE". Sin embargo, podría crear una nueva tabla con la misma definición que la actual, aunque con un nombre diferente, con las columnas en el orden correcto de la manera que desee. Copie los datos en la nueva tabla. Suelta la vieja mesa. Cambie el nombre de la nueva tabla para que coincida con el nombre de la tabla anterior.

Tom Kyte tiene un artículo sobre esto en AskTom link text

8

La ubicación de la columna en la tabla debe ser importante (a menos que haya "tamaños de página" a tener en cuenta, o lo que sea Oracle utiliza para almacenar en realidad los datos) Lo que es más importante para el consumidor es cómo se llaman los resultados, es decir, la declaración Select.

5

cambie el nombre de YOUR_ORIGINAL_TABLE como YOUR_NEW_TABLE;

crear la tabla YOUR_ORIGINAL_TABLE NOLOGGING/* o irrecuperable */ como seleccione la columna 1, columna 2, NEW_COLUMN, Columna3 de YOUR_NEW_TABLE;

Drop table YOUR_NEW_TABLE;

Seleccionar * De YOUR_ORIGINAL_TABLE; < < < < < Ahora verá la nueva columna en el medio de la tabla.

¿Pero por qué querrías hacerlo?Parece ilógico. Nunca debe asumir el orden de las columnas y simplemente usar la lista de columnas con nombre si el orden de las columnas es importante.

+1

Es más una cosa de estética que otra cosa. Los datos que se almacenan proceden de una fuente externa (XML) en la que agregaron un campo en medio de sus datos. Por lo tanto, es una pena que nuestra tabla esté ahora en el mismo orden que el XML para todas las columnas menos una. – larf311

2

¿Por qué importa el orden de las columnas? ¿Siempre puede modificarlo en su declaración seleccionada?

Existe la ventaja de agregar nuevas columnas al final de la tabla. Si hay un código que ingenuamente hace un "SELECCIONAR *" y luego analiza los campos en orden, no se romperá el código antiguo añadiendo nuevas columnas al final. Si agrega nuevas columnas en el medio de la tabla, es posible que se rompa el código anterior.

En un trabajo, tenía un DBA que era súper anal sobre "Nunca hacer" SELECT * '". Insistió en que siempre escriba los campos específicos.

+1

Y tu dba fue absoletamente correcto para hacerlo. Select * puede romper una cantidad asombrosa de cosas y si tiene alguna unión devuelve más campos de datos de los que necesita (los campos de combinación están duplicados) y por lo tanto desperdicia recursos de red y base de datos preciosos. – HLGEM

2

Tenga en cuenta que, debajo de las tablas, todos los datos en los registros de la tabla están pegados. Agregar una columna al final de una tabla [si es nula o (en versiones posteriores) no nulo con un valor predeterminado] solo significa un cambio en los metadatos de la tabla. Agregar una columna en el medio requeriría volver a escribir cada registro en esa tabla para agregar el valor apropiado (o marcadores) para esa columna. En algunos casos, eso puede significar que los registros ocupan más espacio en los bloques y algunos registros deben migrarse. En resumen, es una gran cantidad de esfuerzo IO para una tabla de cualquier tamaño real.

Siempre se puede crear una vista de la tabla que tiene las columnas en el orden preferido y utilizar ese punto de vista en una instrucción DML del mismo modo que la mesa

-1

1) La autorización así que usted no puede hacerlo directamente . No necesitamos post tras mensaje diciendo lo mismo, ¿verdad?

2) Ok, el orden de las columnas en una tabla no importa técnicamente. Pero ese no es el punto, la pregunta original simplemente preguntaba si podrías o no podrías hacerlo. No suponga que conoce los requisitos de los demás. Tal vez tengan una tabla con 100 columnas que actualmente se consulta utilizando "SELECT * ..." dentro de una consulta monstruosamente pirateada que preferirían no tratar de desenredar, y mucho menos reemplazar "*" con 100 nombres de columna. O tal vez solo son anal sobre el orden de las cosas y les gusta tener campos relacionados uno junto al otro cuando navegan por el esquema, digamos SQL Developer. Tal vez están tratando con personal no técnico que no sabrá mirar el final de una lista de 100 columnas cuando, lógicamente, debería estar en algún lugar cerca del comienzo.

Nada es más irritante que hacer una pregunta honesta y obtener una respuesta que diga: "no deberías estar haciendo eso". ¡Es MI trabajo, no TUYO! Por favor, no me digas cómo hacer mi trabajo. Sólo ayuda si puedes. ¡Gracias!

Ok ... disculpe la queja. Ahora ... en www.orafaq.com sugiere esta solución.

Primero supongamos que ya ha ejecutado:

CREAR TABLA Tab1 (NÚMERO col1);

Ahora diga que quiere agregar una columna llamada "col2", pero quiere que le pidan "col2", "col1" al hacer un "SELECT * FROM tbl1;"

La sugerencia es ejecutar:

ALTER TABLE ADD Tab1 (FECHA col2); RENOMBRAR tab1 TO tab1_old; CREATE TABLE tab1 AS SELECT 0 AS col1, col1 AS col2 FROM tab1_old;

Me pareció increíblemente engañoso. En primer lugar, está llenando "col1" con cero así que, si tenía datos, entonces los está perdiendo al hacer esto.En segundo lugar, en realidad está cambiando el nombre de "col1" por "col2" y no menciona esto. Por lo tanto, aquí está mi ejemplo, es de esperar que es un poco más claro:

Suponga que tiene una tabla que se creó con la siguiente declaración:

CREATE TABLE usuarios (varchar nombre apellido (25), varchar apellidos (25));

Ahora diga que quiere insertar middle_name entre first_name y last_name. Aquí hay una forma:

ALTER TABLE usuarios ADD middle_name varchar (25); RENOMBRAR usuarios TO users_tmp; CREAR usuarios de TABLE AS SELECT first_name, middle_name, last_name FROM users_tmp; /* y para una buena medida ... */ DROP TABLE testusers_tmp;

Tenga en cuenta que middle_name tendrá como valor predeterminado NULL (implícito en la sentencia ALTER TABLE). Alternativamente, puede establecer un valor predeterminado diferente en la instrucción CREATE TABLE de esta forma:

CREAR usuarios de TABLE AS SELECT first_name, 'algún valor predeterminado' AS middle_name, last_name FROM users_tmp;

Este truco puede ser útil si está agregando un campo de fecha con un valor predeterminado de sysdate, pero desea que todos los registros existentes tengan algún otro valor de fecha (por ejemplo, anterior).

Cuestiones relacionadas