Изменить тип столбца с номерами с varchar на int - PullRequest
29 голосов
/ 23 февраля 2009

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

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

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

Ответы [ 4 ]

35 голосов
/ 23 февраля 2009

Единственный надежный способ сделать это будет использовать временную таблицу, но это не будет много 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
22 голосов
/ 16 мая 2014

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

alter table myTable alter column vColumn int;

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

  1. все данные поместятся в int
  2. все данные могут быть преобразованы в int (т. Е. Значение «car» не будет выполнено)
  3. Нет индексов, включающих vColumn. Если есть индексы, вам нужно будет включить их и создать, чтобы они вернулись туда, где вы были.
7 голосов
/ 23 февраля 2009

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

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

1 голос
/ 27 марта 2013

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

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

  1. Если в таблице определен столбец identity , вам нужно будет включить или выключить 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...