2009-06-08 9 views
5

Estoy intentando modificar una tabla en el servidor SQL con una secuencia de comandos. En el pasado, siempre he hecho este tipo de cosas a través de una GUI, pero ahora necesito generar un script para los clientes.Insertar columna entre otras columnas en SQL Server usando la secuencia de comandos

que tienen una tabla de base de datos SQL Server que es así:

 
MyTable 
------- 
ColA int NOT NULL 
ColB int NOT NULL 
ColC int NOT NULL 
ColD VARCHAR(100) 

La clave principal se define a través de Cola, ColB y ColC.

Quiero la secuencia de comandos SQL para cambiar la tabla de este modo:

 
MyTable 
------- 
ColA int NOT NULL 
ColB int NOT NULL 
ColX int NOT NULL (new column, default 0 for existing data) 
ColC int NOT NULL 
ColD VARCHAR(100) 

La clave principal ahora se define por Cola, ColB, COLX y ColC.

Esto es fácil de hacer a través de la GUI de SQL Server. Pero cuando lo tengo generar un script a partir de eso, parece innecesariamente complejo. Básicamente, la secuencia de comandos crea una tabla temporal con el nuevo esquema, copia todos los datos, índices y restricciones de la tabla anterior en la tabla temporal, borra la tabla anterior, luego cambia el nombre de la nueva por el nombre de la anterior. Además, cuenta con líneas de este tipo:

ALTER TABLE dbo.Tmp_MyTable ADD CONSTRAINT 
    MyTable21792984_ColC_DF DEFAULT ((0)) FOR ColC 

Me preocupa que estos números de aspecto al azar allí (es decir, 21792984) no serán los mismos en todas las instancias de base de datos de clientes. Se ven como algo que el servidor SQL genera al crear la base de datos que sería única para cada instancia.

¿Existe una manera más directa de cambiar la tabla mediante comandos SQL? Miré en línea, pero lo que encontré es básicamente básico y/o genérico.

Actualización: De las respuestas que he recibido, parece que la dificultad radica en poner la nueva columna "entre" dos columnas. Me di cuenta de que realmente no importa en qué orden se encuentran las columnas (si estoy equivocado, no duden en dejar una respuesta corrigiéndome). En mi caso, el cambio es mucho más simple si solo agrego la columna al final de la tabla, y nada en el código se basa en el orden específico de la columna.

Respuesta

8

No hay otra manera de insertar una columna en una tabla de SQL Server "entre" columnas existentes: es necesario crear una tabla temporal y reconstruir la tabla anterior. Dicho eso, el orden de las columnas no debería importar: ¿está seguro de que la columna debe insertarse en orden?

Posiblemente su mejor opción sea simplemente usar la GUI, guiarla y luego cambiar el nombre de la restricción a algo razonable dentro del guión. Tiene razón en que el nombre de la restricción numérica no es ideal, y no es una buena práctica permitir que SQL Server determine sus nombres de objeto.

+0

Gracias, en un examen más detallado, el orden de las columnas no importa (excepto estéticamente). Solo agregar la columna al final lo hace una tarea mucho más fácil. – Kip

+0

Si realmente desea que se modifique la orden, puede usar el orden Forzar columna en SQL Compare para hacer esto. Esto requiere una reconstrucción completa de la tabla, por lo que podría tomar tiempo si tiene una gran cantidad de datos. Los datos existentes serán preservados por SQL Compare. –

3

Si está insertando un campo en el medio de la tabla, esencialmente tiene que soltar la tabla actual y volver a crearla, que es lo que está haciendo el servidor sql.

Los números aleatorios se están asegurando de que la restricción tenga un nombre único. Si conserva el script y lo ejecuta en múltiples bases de datos, todos serán iguales. Si va a modificar cada uno a través de la interfaz gráfica, entonces sí, lo más probable es que sean diferentes.

Para modificar la clave principal, todo lo que necesita hacer es averiguar el nombre de la restricción de la clave primaria y soltarla. Solo agregue una nueva restricción que defina la clave principal. Esto supone que no tiene la clave principal enumerada como una clave externa en otro lugar.

1

Si quiere la columna en el medio así, eso es lo que tiene que hacer. He encontrado que los scripts que genera son bastante buenos para incluir solo el trabajo necesario.

Si se va a añadir una columna al final, por ejemplo, sólo se tiene que hacer:

ALTER TABLE ADD COLUMN ColX int NOT NULL DEFAULT(0) 

Y se podría ver esto en la secuencia de comandos que genera.

En cuanto a la alteración de la clave principal, se puede descartar (en todas las columnas existentes) y recrear sin reescribir la tabla, pero si está agrupada o no, probablemente obtenga una secuencia de comandos diferente.

1

Tome el código de muestra & modifíquelo. Si desea que la columna aterrice en un lugar determinado, tendrá que ir a la tabla temporal para redefinir/cambiar el nombre de la ruta. También puede nombrar los índices y las restricciones que desee de esta manera.

1

Qué herramienta usas para generar secuencias de comandos. Yo uso Red-Gate Sql compare tool, y funciona muy bien.

+0

Solo estoy usando Microsoft SQL Server Management Studio, que creo que viene con SQL Server. – Kip

2

Si en su CREATE TABLE acaba de especificar, por ejemplo, PRIMARY KEY (ColA, ColB, ColC), le decía a SQL Server que no le importaba el nombre de esta restricción, que nunca tendría que referirse a ella directamente, por lo que SQL Server estaba completamente justificado al generar un nombre único de aspecto semialeatorio para él, como el MyTable21792984_ColC_DF que con razón le preocupa (aunque esa particular parece ser una restricción de columna única ColC, el mismo tipo de nomenclatura se aplicará a otras restricciones))

Si bien es probable que este problema sea demasiado tarde para solucionar su esquema actual, le ayudaría en el futuro si siguiera el principio de , siempre nombre sus restricciones, ya que generalmente es posible que tenga que referirse para ellos en el futuro, por lo que desea que el nombre esté completamente bajo su control, al igual que el nombre de cualquier otro objeto de esquema (tabla, columna, etc.). En este caso, usar una cláusula como CONSTRAINT PK_MyTable PRIMARY KEY (ColA, ColB, ColC) en el CREATE TABLE hubiera sido útil. (Si las herramientas de GUI que está utilizando para sus tareas de DBA no le permiten controlar este tipo de cosas, no son herramientas adecuadas para un DBA: ¡encuentre mejores!).

+0

Lamentablemente, estoy llegando a los datos existentes, por lo que no tengo ningún control sobre cómo se crearon las bases de datos. Pero al menos nombran sus claves principales consistentemente como PK_TableName. – Kip

2

No es una buena práctica depender de ningún tipo de ordenamiento "natural" o "inherente" de columnas en una tabla de base de datos. Todas las columnas deben llamarse por nombre en cualquier consulta generada oficialmente para devolver las columnas por nombre en el orden especificado por la consulta. Si no se sigue esa regla, cualquier cambio de esquema futuro es una pesadilla absoluta, ya que es posible que sea necesario cambiar el código del sistema cada vez que se actualice el esquema de la base de datos.

Lo único molesto aquí sería cuando se ejecutan consultas únicas usando SELECT * FROM ... en las bases de datos de producción/prueba/desarrollo codificadas manualmente por los usuarios y teniendo su nueva columna al final de la lista de columnas. Sin embargo, creo que muchas herramientas de consulta le permitirán reordenar las columnas desde una especie de GUI.

3

Solo quiero señalar por qué nunca desea utilizar la GUI para insertar una columna en el medio de una tabla existente. Cuando lo haces, crea una nueva tabla secreta, mueve los datos de la tabla anterior, cambia el nombre de la tabla anterior, cambia el nombre de la nueva tabla al nombre de tabla anterior y descarta la tabla anterior. Esto es suficientemente malo si tienes un pequeño conjunto de datos. En un mundo de producción donde las tablas pueden ser bastante grandes, podría estar bloqueando a los usuarios el acceso a la tabla durante varias horas. Cualquier diseño de base de datos en el que el orden de las columnas de la base de datos deba reordenarse cuando se agregue una nueva columna es una base de datos para desastres.Debido a que hay personas que insisten en hacer esto, es otra razón por la cual Select * también es un problema que está por ocurrir. Realmente no desea que el estado se muestre en su columna zip en un informe porque alguien reordenó las columnas en la tabla y se basó en seleccionar * del orden de las columnas.

+0

Las interfaces GUI hacen que parezca tan sencillo reorganizar las columnas, especialmente porque se usan en pequeñas bases de datos de desarrollo donde la capacidad de duplicar una tabla es insignificante, ¡no tenía ni idea de que se estaba trabajando tanto detrás de escena! – Kip

+3

Ah, y usted nunca debería hacer dev en una base de datos significativamente más pequeña que su base de datos prod. Las consultas que funcionan mejor para pequeños conjuntos de datos NO son las consultas que funcionan mejor para grandes conjuntos de datos. Esto causa sistemas que funcionan muy mal. – HLGEM

0

Agregue la nueva columna a la tabla existente. (Se agrega al final de todas las columnas) Luego cree una nueva tabla usando esta tabla y en la subconsulta que se usa para construir la nueva tabla, mencione las columnas el orden en que se desea en la nueva tabla ..

Ex:

create table person(name varchar2(10),age number); 
alter table person add salary number; (now salary is added at last position) 
desc person 
name ... 
age ... 
salary ... so now salary is at the end. 

decir ahora quiero crear tabla de empleados utilizando esta tabla persona.

create table employee as select name,salary,age from person; 

al describir tabla de empleados que tiene la definición que la persona de la mesa, así como datos.

Cuestiones relacionadas