Как добавить столбец в TSQL после определенного столбца?
у меня есть таблица:
MyTable
ID
FieldA
FieldB
Я хочу изменить таблицу и добавить столбец, чтобы он выглядел так:
MyTable
ID
NewField
FieldA
FieldB
в MySQL я бы так:
ALTER TABLE MyTable ADD COLUMN NewField int NULL AFTER ID;
одна строка, хорошая, простая, отлично работает. Как это сделать в мире Microsoft?
9 ответов
к сожалению вы не можете.
Если вы действительно хотите, чтобы они были в этом порядке, вам придется создать новую таблицу со столбцами в этом порядке и скопировать данные. Или переименовать столбцы и т. д. Легкого пути нет.
устранение:
это будет работать для таблиц, где нет зависимостей от меняющейся таблицы, которая вызовет каскадные события. сначала убедитесь, что вы можете уронить таблицу, которую хотите реструктурировать, без каких-либо катастрофических последствий. обратите внимание на все зависимости и ограничения столбцов, связанные с вашей таблицей (т. е. триггеры, индексы и т. д.). Возможно, вам придется положить их обратно, когда вы сделали.
шаг 1: создать временную таблицу для хранения всех записей из таблицы, которую вы хотите перестроиться. Не забудьте включить новый столбец.
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
)
Шаг 2: убедитесь, что все записи были скопированы и что структура столбца выглядит так, как вы хотите.
SELECT TOP 10 * FROM #tmp_myTable ORDER BY 1 DESC
-- вы можете сделать счет (*) или что-нибудь, чтобы убедиться, что вы скопировали все записи
Шаг 3: отбросьте оригинал таблица:
DROP TABLE myTable
если вы параноик о плохих вещах может произойти, просто переименуйте исходную таблицу (вместо того, чтобы отбрасывать ее). Таким образом, его всегда можно вернуть обратно.
EXEC sp_rename myTable, myTable_Copy
Шаг 4: воссоздать таблицу myTable так, как вы хотите (должно соответствовать #tmp_myTable таблица структура)
CREATE TABLE myTable
( [new_column] [int] NOT NULL,
[idx] [bigint] NOT NULL,
[name] [nvarchar](30) NOT NULL,
[active] [bit] NOT NULL
)
-- не забывайте о любых ограничениях, которые вам могут понадобиться
Шаг 5: скопировать все записи из temp #tmp_myTable таблица в новую (улучшенную) таблицу таблица mytable.
INSERT INTO myTable ([new_column],[idx],[name],[active])
SELECT [new_column],[idx],[name],[active]
FROM #tmp_myTable
Шаг 6: Проверьте, все ли данные вернулись в вашу новую, улучшенную таблицу таблица mytable. Если да, очистите после себя и отбросьте таблицу temp #tmp_myTable и myTable_Copy таблица, Если вы решили переименовать его вместо того, чтобы удалить его.
вы сможете сделать это, если создадите столбец с помощью GUI в Management Studio. Я считаю, что Management studio фактически полностью воссоздает таблицу,поэтому это происходит.
Как упоминали другие, порядок столбцов в таблице не имеет значения, и если это так, с вашим кодом что-то не так.
/* Скрипт для изменения порядка столбцов таблицы
При этом будет создана новая таблица, чтобы заменить исходную таблицу
Однако он не копирует триггеры или другие свойства таблицы - только данные
*/
создайте новую таблицу со столбцами в том порядке, в котором вам требуется
Select Column2, Column1, Column3 Into NewTable from OldTable
удалить оригинальный таблица
Drop Table OldTable;
переименовать новую таблицу
EXEC sp_rename 'NewTable', 'OldTable';
вам нужно перестроить таблицу. К счастью, порядок колонн не имеет никакого значения!
смотреть, как я волшебным образом изменить порядок столбцов:
SELECT ID, Newfield, FieldA, FieldB FROM MyTable
также об этом спрашивали миллион раз раньше.
в Microsoft SQL Server Management Studio (инструмент администрирования MSSQL) просто перейдите в раздел "дизайн" таблицы и перетащите столбец в новое положение. Не командная строка, но вы можете это сделать.
в SQL Enterprise Management Studio откройте таблицу, добавьте столбец, где вы хотите, а затем-вместо сохранения изменения-создайте сценарий изменения. Вы можете увидеть, как это делается в SQL.
короче, то, что другие сказали правильно. Среда SQL Management studio собирает все данные во временную таблицу, отбрасывает таблицу, воссоздает ее со столбцами в правильном порядке и помещает данные временной таблицы обратно. Нет простого синтаксиса для добавления столбца в определенный позиция.
даже если вопрос старый, более точный о студии управления потребуется.
столбец можно создать вручную или с помощью Management Studio. Но Management Studio потребует воссоздать таблицу и приведет к тайм-ауту, если у вас уже слишком много данных в ней, избегайте, если таблица не светлая.
чтобы изменить порядок столбцов, вам просто нужно переместить их в Management Studio. Это не должно требовать (скорее всего, исключения существует), чтобы среда Management Studio воссоздала таблицу, поскольку она, скорее всего, изменит порядок столбцов в определениях таблиц.
Я делал это так много раз с таблицами, которые я не мог добавить столбцы с GUI из-за данных в них. Затем переместил столбцы с помощью GUI Management Studio и просто сохранил их.
вы будете идти от гарантированного тайм-аута до нескольких секунд ожидания.
Это абсолютно возможно. Хотя вы не должны этого делать, если не знаете, с чем имеете дело. Мне потребовалось около 2 дней, чтобы понять это. Вот хранимая процедура, в которую я ввожу: ---имя базы данных (имя схемы - " _ " для удобства чтения) ---имя таблицы ---столбец ---тип данных столбца (добавленный столбец всегда равен null, иначе вы не сможете вставить) --- положение новой колонки.
поскольку я работаю с таблицами из Sam toolkit (и некоторые из них имеют > 80 столбцов) , типичная переменная не сможет содержать запрос. Это вызывает необходимость внешнего файла. Теперь будьте осторожны, где вы храните этот файл и у кого есть доступ к NTFS и сетевому уровню.
Ура!
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 ')
конец