web-dev-qa-db-fra.com

Comment ajouter une colonne en SQL après une colonne spécifique?

J'ai une table:

MyTable
    ID
    FieldA
    FieldB

Je veux modifier le tableau et ajouter une colonne pour ressembler à ceci:

MyTable
    ID
    NewField
    FieldA
    FieldB

Dans MySQL, je voudrais donc:

ALTER TABLE MyTable ADD COLUMN NewField int NULL AFTER ID;

Une ligne, simple, simple, fonctionne très bien. Comment puis-je faire cela dans le monde de Microsoft?

32
Justin808

Malheureusement, vous ne pouvez pas.

Si vous les voulez vraiment dans cet ordre, vous devrez créer un nouveau tableau avec les colonnes dans cet ordre et copier les données. Ou renommer des colonnes, etc. Il n'y a pas de moyen facile.

31
Mike M.

solution:

Cela fonctionnera pour les tables où il n'y a pas de dépendances sur la table à langer qui pourraient déclencher des événements en cascade.Tout d’abord, assurez-vous de pouvoir supprimer la table que vous souhaitez restructurer sans répercussions désastreuses.Prenez note de toutes les dépendances et contraintes de colonne associées à votre table (déclencheurs, index, etc.). Vous devrez peut-être les remettre lorsque vous aurez terminé.

ÉTAPE 1: créez la table temporaire pour contenir tous les enregistrements de la table que vous souhaitez restructurer. N'oubliez pas d'inclure la colonnenouvelle.

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
)

ÉTAPE 2: Assurez-vous que tous les enregistrements ont été copiés et que la structure de la colonne se présente comme vous le souhaitez.

SELECT TOP 10 * FROM #tmp_myTable ORDER BY 1 DESC-- vous pouvez faire COUNT (*) ou n’importe quoi pour vous assurer que vous avez copié tous les enregistrements

ÉTAPE 3: DROP la table d'origine:

DROP TABLE myTable

Si vous êtes paranoïaque à propos de mauvaises choses, il vous suffit de renommer la table d'origine (au lieu de la supprimer). De cette façon, il peut toujours être retourné.

EXEC sp_rename myTable, myTable_Copy

ÉTAPE 4: Recréez la table myTable comme vous le souhaitez (doit correspondre à la structure #tmp_myTable structure de la table)

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

- N'oubliez pas les contraintes dont vous pourriez avoir besoin

ÉTAPE 5: Copiez tous les enregistrements de la table temp #tmp_myTable table dans la nouvelle table (améliorée) myTable .

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

ÉTAPE 6: Vérifiez si toutes les données figurent dans votre nouveau tableau amélioré myTable . Si tel est le cas, nettoyez après vous et supprimez la table temporaire #tmp_myTable et la table myTable_Copy si vous avez choisi de la renommer au lieu de la supprimer.

6
Milan

Vous devriez pouvoir le faire si vous créez la colonne à l'aide de l'interface graphique de Management Studio. Je pense que Management Studio est en train de recréer complètement la table, c'est pourquoi cela semble se produire.

Comme d'autres l'ont mentionné, l'ordre des colonnes dans un tableau n'a pas d'importance, et si c'est le cas, il y a un problème avec votre code.

3
Abe Miessler

/ * Script pour changer l'ordre des colonnes d'une table
Notez que cela va créer une nouvelle table pour remplacer la table d'origine
CEPENDANT, il ne copie pas les déclencheurs ni d’autres propriétés de table, mais uniquement les données.
* /

Générez une nouvelle table avec les colonnes dans l'ordre de votre choix

Select Column2, Column1, Column3 Into NewTable from OldTable

Supprimer la table d'origine

Drop Table OldTable;

Renommez la nouvelle table

EXEC sp_rename 'NewTable', 'OldTable';

2
Glyn

Dans SQL Enterprise Management Studio, ouvrez votre table, ajoutez la colonne où vous le souhaitez, puis, au lieu d'enregistrer la modification, générez le script de modification. Vous pouvez voir comment cela se passe en SQL.

En bref, ce que d’autres ont dit est juste. SQL Management studio récupère toutes vos données dans une table temporaire, la supprime, la recrée avec les colonnes dans le bon ordre et y replace les données de la table temporaire. Il n’existe pas de syntaxe simple pour l’ajout d’une colonne à une position spécifique.

1
user2124444

Vous devez reconstruire la table. Heureusement, l'ordre des colonnes n'a pas d'importance!

Regardez comme je réorganise comme par magie vos colonnes:

SELECT ID, Newfield, FieldA, FieldB FROM MyTable

En outre, cela a été demandé à propos d'un bazillion fois auparavant.

1
JNK

Dans Microsoft SQL Server Management Studio (l'outil d'administration de MSSQL), entrez simplement dans "Design" sur une table et faites glisser la colonne vers le nouvel emplacement. Pas de ligne de commande mais vous pouvez le faire.

1
paparazzo

C'est absolument possible. Bien que vous ne devriez pas le faire à moins que vous sachiez à quoi vous avez affaire. Il m'a fallu environ 2 jours pour le comprendre. Voici une procédure stockée dans laquelle je saisis: --- nom de la base de données (Nom du schéma: "_" pour la lisibilité) --- nom de la table --- colonne --- type de données de la colonne (la colonne ajoutée est toujours nulle, sinon vous ne pourrez pas l'insérer) --- la position de la nouvelle colonne.

Comme je travaille avec des tables de la boîte à outils SAM (et que certaines d’entre elles ont plus de 80 colonnes), la variable type ne pourra pas contenir la requête. Cela oblige le besoin de fichier externe. Maintenant, faites attention où vous stockez ce fichier et qui a accès au NTFS et au niveau du réseau.

À votre santé!

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
Zlatin Todorinski

Même si la question est ancienne, une réponse plus précise à propos de Management Studio serait nécessaire.

Vous pouvez créer la colonne manuellement ou avec Management Studio. Mais Management Studio nécessitera de recréer la table et entraînera un délai d'expiration si vous avez déjà trop de données dans celle-ci, évitez si la table est légère.

Pour changer l'ordre des colonnes, il vous suffit de les déplacer dans Management Studio. Cela ne devrait pas obliger (il est fort probable qu'il existe des exceptions) que Management Studio recrée la table, car cela modifie probablement l'ordination des colonnes dans les définitions de table.

Je l'ai fait ainsi à de nombreuses reprises avec des tables pour lesquelles je ne pouvais pas ajouter de colonnes avec l'interface graphique à cause des données qu'elles contiennent. Déplacez ensuite les colonnes avec l'interface graphique de Management Studio et sauvegardez-les simplement.

Vous passerez d’une pause assurée à quelques secondes d’attente.

0
Rv3