Cómo agregar una columna en TSQL después de una columna específica?


Tengo una tabla:

MyTable
    ID
    FieldA
    FieldB

Quiero alterar la tabla y agregar una columna para que se vea como:

MyTable
    ID
    NewField
    FieldA
    FieldB

En MySQL lo haría a:

ALTER TABLE MyTable ADD COLUMN NewField int NULL AFTER ID;

Una línea, agradable, simple, funciona muy bien. ¿Cómo hago esto en el mundo de Microsoft?

Author: Justin808, 2011-10-28

9 answers

Desafortunadamente no puedes.

Si realmente las quieres en ese orden tendrás que crear una nueva tabla con las columnas en ese orden y copiar los datos. O renombrar columnas, etc. No hay una manera fácil.

 29
Author: Mike M.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-28 18:21:54

Solución:

Esto funcionará para tablas donde no hay dependencias en la tabla cambiante que desencadenarían eventos en cascada. En primer lugar, asegúrese de que puede dejar caer la tabla que desea reestructurar sin repercusiones desastrosas. Tome nota de todas las dependencias y restricciones de columna asociadas con su tabla (es decir, disparadores, índices, etc.).). Es posible que tenga que volver a colocarlos cuando haya terminado.

PASO 1: crear la tabla temporal para mantenga todos los registros de la tabla que desea reestructurar. No se olvide de incluir el nueva columna.

CREATE TABLE #tmp_myTable
(   [new_column] [int] NOT NULL, <-- new column has been inserted here!
    [idx] [bigint] NOT NULL,
    [name] [nvarchar](30) NOT NULL,
    [active] [bit] NOT NULL
)

PASO 2: Asegúrese de que todos los registros se hayan copiado y que la estructura de columnas se vea de la manera que desea.

SELECT TOP 10 * FROM #tmp_myTable ORDER BY 1 DESC -- puede hacer COUNT(*) o cualquier cosa para asegurarse de que copió todos los registros

PASO 3: ELIMINAR la tabla original:

DROP TABLE myTable

Si usted es paranoico acerca de cosas malas podrían suceder, solo cambie el nombre de la tabla original (en lugar de soltarla). De esta manera siempre se puede devolver.

EXEC sp_rename myTable, myTable_Copy

PASO 4: Vuelva a crear la tabla MyTable de la manera que desee (debe coincidir con la estructura de la tabla #tmp_myTable)

CREATE TABLE myTable
(   [new_column] [int] NOT NULL,
    [idx] [bigint] NOT NULL,
    [name] [nvarchar](30) NOT NULL,
    [active] [bit] NOT NULL
)

Not no olvide las restricciones que pueda necesitar

PASO 5: Copie todos los registros de la tabla temp #tmp_myTable en la nueva tabla (mejorada) MyTable.

INSERT INTO myTable ([new_column],[idx],[name],[active])
SELECT [new_column],[idx],[name],[active]
FROM #tmp_myTable

PASO 6: Compruebe si todos los los datos están de vuelta en su nueva tabla mejorada MyTable . Si es así, limpia después de ti mismo y SUELTA la tabla temp #tmp_myTable y la tabla myTable_Copy si eliges cambiarle el nombre en lugar de soltarla.

 5
Author: Milan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-06 18:19:30

Debería poder hacer esto si crea la columna usando la GUI en Management Studio. Creo que Management studio está recreando completamente la mesa, por lo que esto parece suceder.

Como otros han mencionado, el orden de las columnas en una tabla no importa, y si lo hace, hay algo mal con su código.

 3
Author: Abe Miessler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-28 18:25:02

/* Script para cambiar el orden de las columnas de una tabla
Tenga en cuenta que esto creará una nueva tabla para reemplazar la tabla original
SIN embargo, no copia los disparadores u otras propiedades de la tabla, solo los datos
*/

Genere una nueva tabla con las columnas en el orden que necesite

Select Column2, Column1, Column3 Into NewTable from OldTable

Suprímase el cuadro original

Drop Table OldTable;

Cambiar el nombre de la nueva tabla

EXEC sp_rename 'NewTable', 'OldTable';

 2
Author: Glyn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-12 07:18:56

Tienes que reconstruir la tabla. Afortunadamente, el orden de las columnas no importa en absoluto!

Mira cómo reordeno mágicamente tus columnas:

SELECT ID, Newfield, FieldA, FieldB FROM MyTable

También esto se ha preguntado sobre un bazillion veces antes.

 1
Author: JNK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-28 18:20:55

En Microsoft SQL Server Management Studio (la herramienta de administración para MSSQL) simplemente vaya a "diseño" en una tabla y arrastre la columna a la nueva posición. No la línea de comandos, pero usted puede hacerlo.

 1
Author: paparazzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-29 00:16:26

En SQL Enterprise Management Studio, abra la tabla, agregue la columna donde la desee y, a continuación, en lugar de guardar el cambio, genere el script de cambios. Puedes ver cómo se hace en SQL.

En resumen, lo que otros han dicho es correcto. SQL Management studio extrae todos sus datos en una tabla temporal, suelta la tabla, la recrea con columnas en el orden correcto y vuelve a colocar los datos de la tabla temporal allí. No hay una sintaxis simple para agregar una columna en un posición.

 1
Author: user2124444,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-06 20:15:19

Incluso si la pregunta es antigua, se requeriría un estudio de administración más preciso.

Puede crear la columna manualmente o con Management Studio. Pero Management Studio requerirá recrear la tabla y dará lugar a un tiempo de espera si ya tiene demasiados datos en ella, evite a menos que la tabla sea ligera.

Para cambiar el orden de las columnas, solo tiene que moverlas en Management Studio. Esto no debería requerir (Excepciones muy probablemente existen) que Management Studio para recrear la tabla ya que lo más probable es cambiar la ordenación de las columnas en las definiciones de tabla.

Lo he hecho de esta manera en numerosas ocasiones con tablas que no pude agregar columnas con la GUI debido a los datos en ellas. Luego movió las columnas con la GUI de Management Studio y simplemente las guardó.

Pasará de un tiempo de espera asegurado a unos segundos de espera.

 0
Author: Rv3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-28 02:39:01

Esto es absolutamente posible. Aunque no deberías hacerlo a menos que sepas con lo que estás lidiando. Tardé unos 2 días en averiguarlo. Aquí hay un procedimiento almacenado donde entro: --- nombre de la base de datos (el nombre del esquema es " _ " para la legibilidad) --- nombre de la tabla ---columna ---tipo de datos de columna (la columna añadida siempre es nula, de lo contrario no podrá insertar) ---la posición de la nueva columna.

Dado que estoy trabajando con tablas de SAM toolkit (y algunas de ellas tienen > 80 columnas), el la variable típica no podrá contener la consulta. Eso obliga a la necesidad de archivo externo. Ahora tenga cuidado dónde almacena ese archivo y quién tiene acceso a nivel NTFS y de red.

Salud!

USE [master]
GO
/****** Object:  StoredProcedure [SP_Set].[TrasferDataAtColumnLevel]    Script Date: 8/27/2014 2:59:30 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [SP_Set].[TrasferDataAtColumnLevel]
(
    @database varchar(100),
    @table varchar(100),
    @column varchar(100),
    @position int,
    @datatype varchar(20)    
)
AS
BEGIN
set nocount on
exec  ('
declare  @oldC varchar(200), @oldCDataType varchar(200), @oldCLen int,@oldCPos int
create table Test ( dummy int)
declare @columns varchar(max) = ''''
declare @columnVars varchar(max) = ''''
declare @columnsDecl varchar(max) = ''''
declare @printVars varchar(max) = ''''

DECLARE MY_CURSOR CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY FOR 
select column_name, data_type, character_maximum_length, ORDINAL_POSITION  from ' + @database + '.INFORMATION_SCHEMA.COLUMNS where table_name = ''' + @table + '''
OPEN MY_CURSOR FETCH NEXT FROM MY_CURSOR INTO @oldC, @oldCDataType, @oldCLen, @oldCPos WHILE @@FETCH_STATUS = 0 BEGIN

if(@oldCPos = ' + @position + ')
begin
    exec(''alter table Test add [' + @column + '] ' + @datatype + ' null'')
end

if(@oldCDataType != ''timestamp'')
begin

    set @columns += @oldC + '' , '' 
    set @columnVars += ''@'' + @oldC + '' , ''

    if(@oldCLen is null)
    begin
        if(@oldCDataType != ''uniqueidentifier'')
        begin
            set @printVars += '' print convert('' + @oldCDataType + '',@'' + @oldC + '')'' 
            set @columnsDecl += ''@'' + @oldC + '' '' + @oldCDataType + '', '' 
            exec(''alter table Test add ['' + @oldC + ''] '' + @oldCDataType + '' null'')
        end
        else
        begin
            set @printVars += '' print convert(varchar(50),@'' + @oldC + '')'' 
            set @columnsDecl += ''@'' + @oldC + '' '' + @oldCDataType + '', '' 
            exec(''alter table Test add ['' + @oldC + ''] '' + @oldCDataType + '' null'')
        end
    end
    else
    begin 
        if(@oldCLen < 0)
        begin
            set @oldCLen = 4000
        end
        set @printVars += '' print @'' + @oldC 
        set @columnsDecl += ''@'' + @oldC + '' '' + @oldCDataType + ''('' + convert(character,@oldCLen) + '') , '' 
        exec(''alter table Test add ['' + @oldC + ''] '' + @oldCDataType + ''('' + @oldCLen + '') null'')
    end
end

if exists (select column_name from INFORMATION_SCHEMA.COLUMNS where table_name = ''Test'' and column_name = ''dummy'')
begin
    alter table Test drop column dummy
end

FETCH NEXT FROM MY_CURSOR INTO  @oldC, @oldCDataType, @oldCLen, @oldCPos END CLOSE MY_CURSOR DEALLOCATE MY_CURSOR

set @columns = reverse(substring(reverse(@columns), charindex('','',reverse(@columns)) +1, len(@columns)))
set @columnVars = reverse(substring(reverse(@columnVars), charindex('','',reverse(@columnVars)) +1, len(@columnVars)))
set @columnsDecl = reverse(substring(reverse(@columnsDecl), charindex('','',reverse(@columnsDecl)) +1, len(@columnsDecl)))
set @columns = replace(replace(REPLACE(@columns, ''       '', ''''), char(9) + char(9),'' ''), char(9), '''')
set @columnVars = replace(replace(REPLACE(@columnVars, ''       '', ''''), char(9) + char(9),'' ''), char(9), '''')
set @columnsDecl = replace(replace(REPLACE(@columnsDecl, ''  '', ''''), char(9) + char(9),'' ''),char(9), '''')
set @printVars = REVERSE(substring(reverse(@printVars), charindex(''+'',reverse(@printVars))+1, len(@printVars))) 

create table query (id int identity(1,1), string varchar(max))

insert into query values  (''declare '' + @columnsDecl + ''
DECLARE MY_CURSOR CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY FOR '')

insert into query values   (''select '' + @columns + '' from ' + @database + '._.' + @table + ''')

insert into query values  (''OPEN MY_CURSOR FETCH NEXT FROM MY_CURSOR INTO '' + @columnVars + '' WHILE @@FETCH_STATUS = 0 BEGIN '')

insert into query values   (@printVars )

insert into query values   ( '' insert into Test ('')
insert into query values   (@columns) 
insert into query values   ( '') values ( '' + @columnVars + '')'')

insert into query values  (''FETCH NEXT FROM MY_CURSOR INTO  '' + @columnVars + '' END CLOSE MY_CURSOR DEALLOCATE MY_CURSOR'')

declare @path varchar(100) = ''C:\query.sql''
declare @query varchar(500) = ''bcp "select string from query order by id" queryout '' + @path + '' -t, -c -S  '' + @@servername +  '' -T''

exec master..xp_cmdshell @query

set @query  = ''sqlcmd -S '' + @@servername + '' -i '' + @path

EXEC xp_cmdshell  @query

set @query = ''del ''  + @path

exec xp_cmdshell @query

drop table ' + @database + '._.' + @table + '

select * into ' + @database + '._.' + @table + ' from Test 

drop table query
drop table Test  ')

FIN

 0
Author: Zlatin Todorinski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-27 13:10:35