2009-02-23 104 views
24

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

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

注意:是的,首先将列设置为varchar并不是一个好主意,但不幸的是他们这样做了。

回答

30

的唯一可靠方法,这将使用临时表,但不会有太大的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 
+0

#tmp是一个tmp表的随机名吗? – Svish 2009-02-23 14:02:33

+1

好的答案 - 我将首先运行 - 选择cast(silly_column as int),other_columns from bad_table 确保您没有任何转换问题,它们实际上都是整数。 – brendan 2009-02-23 14:02:50

+3

在我编造的所有名字中,你对#tmp做了评论? – cjk 2009-02-23 14:03:43

8

只要改变数据类型在Management Studio

(你可能需要去到工具>选项>设计师,并禁用选项,以防止保存更改,重新创建表)

1

我完全理解以前的答案,但也认为更完整的答案将有助于其他搜索者...

如果您在生产类型表上进行更改,将会有帮助。

  1. 如果您对表中定义的身份列,你必须设置IDENTITY_INSERT和关闭围绕数据的重新插入。您还必须使用明确的列列表。
  2. 如果你想确保数据库中的不杀生的数据,使用TRANSACTIONS周围的截断/修改/重新插入过程
  3. 如果你有大量的数据,然后试图做到使SQ Server Management Studio中的变化可能会因超时而失败,并且可能会丢失数据。

要扩大@cjk给出的答案,看看下面:

注:“TUC”只是在此脚本真正的表名 开始占位尝试 开始交易

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 
18

做到这一点,最简单的方法是:

alter table myTable alter column vColumn int; 

这将作为LON克作为

  1. 所有的数据将适合内部的int
  2. 所有数据可以被转换为int(即“car”的值将失败)
  3. 没有包含vColumn的索引。如果有索引,则需要包含一个下拉菜单并为它们创建,以便返回到原来的位置。
相关问题