Измените тип столбца с числами с varchar на int

У нас есть два столбца в базе данных, которая в настоящее время имеет тип varchar (16). Дело в том, что он содержит числа и всегда будет содержать числа. Поэтому мы хотим изменить его тип на целое число. Но проблема в том, что он, конечно, уже содержит данные.

Есть ли способ изменить тип этого столбца с varchar на int и не потерять все те числа, которые там уже есть? Надеюсь, что какой-то sql, который мы можем просто запустить, без необходимости создавать временные столбцы и создавать программу C# или что-то для преобразования и т.д. числа, но я очень нестабилен в SQL. Практически работает только с C# и получает доступ к базе данных через LINQ to SQL.

Примечание: Да, изначально сделать столбец varchar было не очень хорошей идеей, но, к сожалению, они сделали это именно так.

Ответов (4)

Решение

Единственный надежный способ сделать это - использовать временную таблицу, но это не будет много SQL:

select * into #tmp from bad_table
truncate table bad_table
alter bad_table alter column silly_column int
insert bad_table
select cast(silly_column as int), other_columns
from #tmp
drop table #tmp

Самый простой способ сделать это:

alter table myTable alter column vColumn int;

Это будет работать до тех пор, пока

  1. все данные поместятся внутри int
  2. все данные можно преобразовать в int (т. е. значение "car" не сработает)
  3. нет индексов, включающих vColumn. Если есть индексы, вам нужно будет включить перетаскивание и создать, чтобы они вернулись туда, где вы были.

Я полностью признателен за предыдущие ответы, но также подумал, что более полный ответ будет полезен другим поисковикам ...

Есть пара предостережений, которые могут быть полезны, если вы вносите изменения в таблицу производственного типа.

  1. Если у вас есть столбец идентификаторов, определенный в таблице, вам придется включать IDENTITY_INSERTи выключать повторную вставку данных. Вам также придется использовать явный список столбцов.
  2. Если вы хотите быть уверенным, что не убиваете данные в базе данных, используйте TRANSACTIONSпроцесс усечения / изменения / повторной вставки
  3. Если у вас много данных, то попытка просто внести изменения в SQ Server Management Studio может завершиться ошибкой с тайм-аутом, и вы можете потерять данные.

Чтобы расширить ответ, который дал @cjk, посмотрите на следующее:

Примечание: 'tuc' в этом скрипте - это просто заполнитель для настоящего имени таблицы.

begin try 
  begin transaction

  print 'Selecting Data...'
  select * into #tmp_tuc from tuc

  print 'Truncating Table...'
  truncate table tuc

  alter table tuc alter column {someColumnName} {someDataType} [not null]
  ... Repeat above until done

  print 'Reinserting data...'
  set identity_insert tuc on
  insert tuc (
    <Explicit column list (all columns in table)>
  )
  select  
    <Explicit column list (all columns in table - same order as above)>
  from #tmp_tuc
  set identity_insert tuc off

  drop table #tmp_tuc
  commit
  print 'Successful!'
end try
begin catch
  print 'Error - Rollback'
  if @@trancount > 0
    rollback

  declare @ErrMsg nvarchar(4000), @ErrSeverity int
  select @ErrMsg = ERROR_MESSAGE(), @ErrSeverity = ERROR_SEVERITY()

  set identity_insert tuc off

  RAISERROR(@ErrMsg, @ErrSeverity, 1)
end catch

Просто измените тип данных в SQL Server Management Studio.

(Возможно, вам придется перейти в меню ИнструментыПараметрыДизайнеры и отключить параметр, предотвращающий сохранение изменений, которые воссоздают таблицу.)