将数字从varchar更改为int的列的类型

时间:2009-02-23 13:58:04

标签: sql-server types

我们在数据库中有两列,目前的类型为varchar(16)。事实是,它包含数字,并且始终包含数字。因此,我们希望将其类型更改为整数。但问题是它当然已包含数据。

我们有什么办法可以将该列的类型从varchar更改为int,而不是丢失那些已存在的那些数字?希望我们可以运行某种sql,而不必创建临时列并创建C#程序或进行转换等等......我想如果SQL Server有一些函数将字符串转换为数字,但我在SQL上非常不稳定。几乎只能使用C#并通过LINQ to SQL访问数据库。

注意:是的,首先让列成为varchar并不是一个好主意,但不幸的是,就像他们这样做了。

4 个答案:

答案 0 :(得分:34)

唯一可行的方法是使用临时表,但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

答案 1 :(得分:22)

最简单的方法是:

alter table myTable alter column vColumn int;

只要

,这将有效
  1. 所有数据都适合int
  2. 所有数据都可以转换为int(即“car”的值将失败)
  3. 没有包含vColumn的索引。如果有索引,则需要包含一个drop并创建它们以回到原来的位置。

答案 2 :(得分:7)

只需更改SQL Server Management Studio中的数据类型。

(您可能需要转到菜单工具选项设计师,并禁用可阻止保存更改的选项表格。)

答案 3 :(得分:1)

我完全赞赏以前的答案,但也认为更完整的答案会对其他搜索者有所帮助......

如果您在生产类型表上进行更改,有几点需要注意。

  1. 如果您在表格中定义了标识列,则必须在重新插入数据时开启和关闭IDENTITY_INSERT。您还必须使用显式列列表。
  2. 如果您想确保不杀死数据库中的数据,请在truncate / alter / reinsert进程周围使用TRANSACTIONS
  3. 如果您有大量数据,那么尝试在SQ Server Management Studio中进行更改可能会因超时而失败,您可能会丢失数据。
  4. 要扩展@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