如何在SQL Server数据库中更改列的数据类型而不丢失数据?

223

我有一个SQL Server数据库,我刚刚意识到可以将其中一列的类型从int更改为bool

如何在不丢失已输入到该表中的数据的情况下实现这一点?


3
你是否尝试创建一个新的二进制列,将旧列中的值复制到新列中,然后删除旧列并重命名新列?当然,这一切都要在事务中进行,以便在出现问题时可以回滚。 - Radu Caprescu
2
你说:“我刚意识到我可以将其中一列的类型从int更改为bool”。实际上,没有布尔数据类型,但有位数据类型。你是在问如何进行这个操作吗(因为前两个回答已经涵盖了这个问题)?还是你的问题是:“我刚才意识到这是可能的 - SQL Server是如何做到的?” - Martin Smith
1
可能是重复的问题:如何在MS SQL中更改列的数据类型? - nandeesh
11个回答

363

你可以使用以下命令轻松完成此操作。任何值为0的都将变成0(BIT = false),而其他任何值都将变成1(BIT = true)。

ALTER TABLE dbo.YourTable
   ALTER COLUMN YourColumnName BIT

另一种选择是创建一个新的BIT类型列,从旧列中填充数据,完成后删除旧列,并将新列重命名为旧名称。这样,如果在转换过程中出现问题,您仍然拥有所有数据,可以随时回退。


11
换句话说:NULL 仍然是 NULL0 变成 False,非零值(1、-1、1999、-987...)变成 True - Álvaro González
2
永远不要通过 GUI 进行此类更改。始终通过像这样的脚本进行更改。GUI 将删除并重新创建表格,这将更耗费时间。如果表格很大且在生产环境中,则可能会造成灾难。此外,所有表格更改都应该有一个与所有其他代码一样在源代码控制中的脚本。 - HLGEM
1
我想要补充的是,在对带有数据的表进行结构更改之前,请确保您拥有该数据库的当前备份。如果该表经常被使用或者很大,请不要在生产环境的高峰使用时间运行此类更改。 - HLGEM

28
ALTER TABLE tablename
ALTER COLUMN columnname columndatatype(size)

注意:如果有列宽,请同时写出列宽大小。


24

如果更改是有效的。

您可以更改该属性。

工具 --> 选项 --> 设计师 --> 表格和数据库设计师 --> 取消勾选 --> 防止保存需要重新创建表格的更改。

现在,您可以轻松更改列名称而无需重新创建表格或丢失记录。


5
绝对不应该使用GUI进行表格更改,否则它会完全重新创建表格而不是使用"Alter table",如果您取消勾选此选项并且表格较大,则会导致问题。此外,您应该将所有表格更改保存在一个脚本中,并放入源代码管理系统中。 - HLGEM
仔细看一下那个选项——它关闭了一个安全选项,该选项将防止GUI删除表。你不会“看起来”丢失数据,因为GUI将重新创建表,但在服务器上,它将是复制/删除。因此,如果表中有大量数据,它将导致非常大的操作。另外,我“认为”(不确定)它发生在单个事务中,因此您可能会填满事务日志。 - JMarsch
1
我想在我的先前评论中添加一些澄清。如果您只是在开发机器上进行此操作,那么您可能没问题。但是,我不建议在生产数据库上使用此方法,特别是如果它是关键任务的数据库。 - JMarsch

11

如果您使用的是T-SQL(MSSQL); 您应该尝试此脚本:

ALTER TABLE [Employee] ALTER COLUMN [Salary] NUMERIC(22,5)

如果您使用MySQL,您应该尝试这个脚本:

ALTER TABLE [Employee] MODIFY COLUMN [Salary] NUMERIC(22,5)

如果你使用Oracle,你应该尝试这个脚本:

ALTER TABLE [Employee] MODIFY [Salary] NUMERIC(22,5)

8

为什么你认为会丢失数据?只需要进入管理工具并更改数据类型即可。如果现有的值可以转换为bool(bit),它就会这样做。换句话说,如果在原始字段中“1”映射到true,“0”映射到false,那么你就没问题了。


1
如果表中有数据,这个方法就不起作用了。当你试图更改列类型时,SMS会声称需要先删除表...当然这是不正确的,因为ALTER TABLE ... ALTER COLUMN命令即使对于非NULL字段也可以正常工作。这就是为什么他们认为可能会丢失数据的原因。 - Tony O'Hagan
1
@TonyO'Hagan 这不是真的。你可以关闭警告,然后它将与现有数据一起正常工作。另请参阅https://dev59.com/yE7Sa4cB1Zd3GeqP1CRt - Philippe Leybaert
1
好的,太酷了!我不知道这个。我试图给你点赞(回报),但是 Stack Overflow 阻止我这样做,除非你编辑你的回答。也许只需要进行一些小修改,我就可以这样做;)。 - Tony O'Hagan
1
在任何情况下,您都不应该使用GUI进行表格更改。它会完全重新创建表格而不是使用Alter table,如果您取消选中此选项并且表格很大,则会导致问题。此外,您应该将所有对表格的更改保存在源代码控制的脚本中。 - HLGEM
在任何情况下都不应该使用GUI来设计表格或更改它们,而且有很多充分的理由不这样做。所有更改都需要在脚本中进行,以便能够传播到其他服务器并像源代码一样在源代码控制中处理。 - HLGEM
1
@HLGEM,这就是数据库项目的用途。 - Jack

4

更改列数据类型并检查列的类型:

IF EXISTS(
       SELECT 1
       FROM   sys.columns
       WHERE  NAME = 'YourColumnName'
              AND [object_id] = OBJECT_ID('dbo.YourTable')
              AND TYPE_NAME(system_type_id) = 'int'
   )
    ALTER TABLE dbo.YourTable ALTER COLUMN YourColumnName BIT

4

打开工具-选项-设计师-表格和数据库设计师,取消勾选“防止保存”选项。enter image description here


4
绝不能使用图形用户界面来进行表格更改,这会完全重新创建表格,而不是使用Alter table,如果勾选了这个选项并且表格很大,这将会导致问题。此外,您应该将所有表格更改都放在源代码控制的脚本中。 - HLGEM

4

对于我来说,在SQL Server 2016中,我会这样做:

*将列Column1重命名为column2

EXEC sp_rename 'dbo.T_Table1.Column1', 'Column2', 'COLUMN'

*将列的类型从字符串修改为整数:(请确保数据格式正确

ALTER TABLE dbo.T_Table1 ALTER COLUMN Column2  int; 

0
在紧凑版中,日期时间数据类型(即(8))的大小将自动调整,因此无需设置字段大小并生成错误。

-3

我可以使用以下查询修改表字段的数据类型,也可以在Oracle数据库中进行修改:

ALTER TABLE table_name
MODIFY column_name datatype;

1
不在SQL Server中 - HLGEM
这应该是 ALTER COLUMN 而不是 MODIFY。 - Nick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接