database - descargar - En Oracle, ¿es posible "insertar" una columna en una tabla?
oracle download (9)
¿Por qué importa el orden de las columnas? ¿Siempre puede modificarlo en su declaración seleccionada?
Hay una ventaja al 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 estará rompiendo 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 super-anal sobre "Never do" SELECT * ''". Insistió en que siempre escriba los campos específicos.
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?
La ubicación de la columna en la tabla no debería ser importante (a menos que haya "tamaños de página" a considerar, o lo que sea que Oracle use para almacenar los datos). Lo que es más importante para el consumidor es cómo se llaman los resultados, es decir, la declaración Select.
Lo que normalmente hago es:
- Cambia el nombre de la tabla anterior.
- Crea la nueva tabla con columnas en el orden correcto.
- Crea las restricciones para esa nueva tabla.
- Rellene con datos: inserte en nueva_tabla seleccione * de la tabla renombrada.
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.
No lo creo, SQL Server tampoco permite esto. El método que siempre tengo que usar es:
- Crear una nueva tabla que se vea bien (incluida una columna adicional)
- Comience la transacción
- seleccione todos los datos de la tabla anterior en uno nuevo
- Dejar la mesa vieja
- Cambiar el nombre de la nueva tabla
- Transacción de compromiso
No es exactamente bonito, pero hace el trabajo.
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 el texto del enlace AskTom
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 puede crear una vista sobre la tabla que tiene las columnas en el orden preferido y usar esa vista en una declaración DML tal como lo haría con la tabla
renombra YOUR_ORIGINAL_TABLE como YOUR_NEW_TABLE;
crea la tabla YOUR_ORIGINAL_TABLE nologging / * o irrecuperable * / como select Column1, Column2, NEW_COLUMN, Column3 from YOUR_NEW_TABLE;
Drop table YOUR_NEW_TABLE;
Seleccione * 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) Ok, entonces no puedes hacerlo directamente. No necesitamos post tras mensaje diciendo lo mismo, ¿verdad?
2) Ok, entonces 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 simplemente preferirían no intentar 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 ... lo siento por la diatriba. Ahora ... en www.orafaq.com sugiere esta solución.
Primero suponga que ya ha corrido:
CREATE TABLE tab1 (col1 NUMBER);
Ahora diga que quiere agregar una columna llamada "col2", pero quiere que se les ordene "col2", "col1" al hacer un "SELECT * FROM tbl1";
La sugerencia es correr:
ALTER TABLE tab1 ADD (col2 DATE); RENAME tab1 TO tab1_old; CREATE TABLE tab1 AS SELECT 0 AS col1, col1 AS col2 FROM tab1_old;
Encontré que esto es 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. Entonces, aquí está mi ejemplo, espero que sea un poco más claro:
Supongamos que tiene una tabla que se creó con la siguiente declaración:
Usuarios de CREATE TABLE (first_name varchar (25), last_name varchar (25));
Ahora di que quieres insertar middle_name entre first_name y last_name. Aquí hay una forma:
Los usuarios de ALTER TABLE ADD middle_name varchar (25); RENOMBRAR usuarios TO users_tmp; Los usuarios de CREATE 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 se convertirá en NULL (implícita en la sentencia ALTER TABLE). Alternativamente, puede establecer un valor predeterminado diferente en la instrucción CREATE TABLE de esta manera:
Los usuarios de CREATE 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).