Sql 如何在不丢失数据的情况下更改表的标识列数据类型

Sql 如何在不丢失数据的情况下更改表的标识列数据类型,sql,sql-server,tsql,ms-access,Sql,Sql Server,Tsql,Ms Access,我负责修复的数据库有一个表,其标识列/PK的数据类型为BigInt。这会导致访问前端出现问题,因为此链接表的数据表不允许编辑记录。这是ODBC驱动程序和Access的已知问题 表的Id列本来不应该被创建为bigint,但现在这是一个没有实际意义的问题。我需要使用int数据类型转换或重新创建此列,而不会丢失现有数据 此表中有约200万条记录。 访问此表的应用程序和访问应用程序的数量未知,因此我正在尝试尽可能平滑/隐蔽地执行此操作,因为在我进行更改之前找到所有这些应用程序并修改它们的可能性很小 有什

我负责修复的数据库有一个表,其标识列/PK的数据类型为BigInt。这会导致访问前端出现问题,因为此链接表的数据表不允许编辑记录。这是ODBC驱动程序和Access的已知问题

表的Id列本来不应该被创建为bigint,但现在这是一个没有实际意义的问题。我需要使用int数据类型转换或重新创建此列,而不会丢失现有数据

此表中有约200万条记录。 访问此表的应用程序和访问应用程序的数量未知,因此我正在尝试尽可能平滑/隐蔽地执行此操作,因为在我进行更改之前找到所有这些应用程序并修改它们的可能性很小


有什么想法或想法吗?

以下是如何从管理学学习中做到这一点:

首先,制作数据库的备份副本。如果发生错误或意外情况,最简单的修复方法是从备份中恢复

在SSMS资源管理器窗格中,导航到该表,然后右键单击该表并单击设计

选择标识列的行并将其数据类型更改为INT

保存更改,忽略警告

如果需要脚本,则将上面的步骤4替换为:

单击“脚本更改”按钮。忽略警告,然后将脚本复制到粘贴缓冲区中。创建一个新的查询窗口并将脚本粘贴到其中。然后关闭“设计”窗口,取消任何更改。
正如斯图尔特·安斯沃思(Stuart Ainsworth)指出的那样,在SQL Server的更高版本中,它可能会阻止您这样做,并警告您不要删除表。若要在SSMS中解决此问题,请单击“工具..选项”菜单项,然后转到“设计器”下的“表格和设计器”窗格,并取消选中“防止保存需要重新创建表格的更改”选项。

我假设IDENTITY列是您的主键,它可能是群集的:我下面的建议基于这些假设

如果表上只有几个索引,并且主键仅由几个外键引用,则应该能够通过以下方式更改数据类型:

删除包含标识值的任何非聚集索引。 删除指向主键的外键约束。 删除主键 ALTER tablename ALTER COLUMN columnname INT; 重新创建主键 使用CHECK重新启用外键约束。 重新创建非聚集索引。
正如RBarryYoung所指出的,如果SSMS GUI配置为允许保存更改,那么其中很多都可以由它编写脚本,但区别在于GUI将创建一个临时表,移动数据,将新表重命名为旧名称,并删除原始表

在Sql Server中,这是相当简单的,但不确定如何保持元数据同步以便访问。我不担心访问元数据。我在SQL中尝试的每件事都告诉我,我必须删除并重新创建您所做的表,但这可以在不丢失任何数据的情况下完成。从guimanagementstudio可以很容易地实现这一点。如果你需要一个SQL脚本,那么让GUI为你做是最简单的。这是一个糟糕的主意,原因很糟糕。不要试图在Access中显示ID列。您可能无论如何都无法编辑它;1:SSM必须配置为允许进行更改以删除数据,这是一个新选项;2:您有时间和空间将200万行数据移动到临时表中。200万行?这就像问你需要5美元钞票的存储空间。200万行可以存储在任何硬移动电话上,除非这是一个图像密集的列。@StuartAinsworth自SQL Server 2005以来,这个特殊的过程一直适用于我。好吧,Allow Drop选项实际上曾经是默认行为,只有在他们将其设置为可配置后,才将默认更改为不允许它。@rbaryyoung我相信这是真的,关闭它很容易,但我认为默认行为现在是DON'T Drop。如果您不指定,那么OP将试图找出发生此错误的原因。@TomTom当然,任何现代服务器都应该能够处理额外的200万行,但您必须承认这会带来一些成本,并且不知道为服务器供电的容量/规格是什么,那么应该澄清的是假设。我的假设是,如果您使用Access作为前端,您可能没有在基础架构上投入太多资金,这是一个假设:我在过去对这两种方法进行了比较,但令人惊讶的是,在性能上没有发现太多差异。显然是ALTER TABLE..ALTER COLUMN。。命令在后台对表进行某种广泛的重建,至少在使用集群键时是这样,这是我实际测试的唯一情况。