如何在不丢失任何数据的情况下更改SQL Server 2005数据库中的主键?

时间:2009-05-14 04:44:52

标签: sql-server database sql-server-2005

我的数据库中有一个表有一个主键,其数据类型是varchar(10),但它只存储了5个char,所以我想将其数据类型从varchar(10)更改为varchar(5)丢失任何数据。

目前我正在创建临时表,将数据从原始表移动到临时表,然后更改它,最后再次将数据从temp恢复到主表。

我想知道这个问题是否有另一种解决方案?

6 个答案:

答案 0 :(得分:1)

我不得不为db2数据库做这个。这些是DBA建议的步骤:

  1. 删除依赖对象,例如视图或过程...请等。在做滴之前保留ddl的副本
  2. 将现有表重命名为_old
  3. 创建具有正确结构的表格。
  4. 在_old table上执行runstats
  5. 将数据从_old表加载到此新表。如果要保留标识列,请使用标识覆盖标志加载
  6. 重新创建视图和过程
  7. 重新绑定所有依赖的过程。
  8. 您可以省略步骤4& 7如果是db2特定的。此外,如果SQLServer中没有概率,则可以省略删除和重新创建依赖对象。

答案 1 :(得分:1)

在大多数DBMS中,运行一个简单的ALTER TABLE语句可以一次完成整个作业,而不会丢失任何数据。你确定MS SQL Server不支持吗? (如果没有,也许你需要一个更好的DBMS - 但我认为这不会是问题。)

看到概述的多步操作,我很困惑。在我主要使用的DBMS中,所有必要的是:

ALTER TABLE WhatEver MODIFY pkcolumn VARCHAR(5) NOT NULL;

它甚至可能是'到位改变';它似乎几乎立即完成,即使实际的变化将在很长一段时间内发生,因为实际的行被改变了。 (好;实际上对于可能不会发生的VARCHAR字段;对于CHAR字段 - 当长度只有5或10个字节时这将是一个不错的选项 - 它将是'就地改变'。)

答案 2 :(得分:1)

由于您指定使用的是SQL Server,因此可以而且应该使用设计工具完成更改。

启动Management Studio程序并连接到服务器。然后打开有问题的数据库并找到该表。

右键单击表格并选择“设计”,然后在该视图中进行更改。

您现在有两个选择:

  1. 您可以单击“保存”按钮,MS SQL Server将为您编写脚本并执行必要的更改
  2. 或者,您可以使用“生成更改脚本”按钮。在我的IDE中,此按钮是与键/约束按钮位于同一工具栏上的最左侧按钮(不是具有“保存”按钮的同一工具栏)
  3. 如果使用后一种功能,您将在对话框中看到脚本代码,并可选择将其保存到磁盘。这使您可以概述如果要执行它将会发生什么。

    更改主键的问题是需要首先删除从其他表到该主键的所有引用,然后重新创建,并且SQL Server Management Studio程序足够智能生成(至少在99百分比的情况)所需的所有SQL,顺序正确。

答案 3 :(得分:0)

我认为您应该创建一个具有标识int主键的表,并使用您的varchar字段作为数据库的唯一替代自然键。

我知道这意味着你必须改变指向那里的任何其他外键,但如果你已经在做你描述的工作,我会全力以赴。

IMHO

答案 4 :(得分:0)

对我来说,我发现必须有价值的方法是创建一个包含以下表达式的备份表:

SELECT *
INTO your_table_name_backup 
FROM your_table_name_original

这将自动生成名称为your_table_name_backup

的表格副本

您现在可以使用drop来更改原始表(your_table_name_original)并创建。

此后

INSERT INTO your_table_name_original SELECT * FROM your_table_name_backup

在那里你没有数据丢失和插入的新表字段类型或约束:)

注意:

我添加写这个,因为没有人将MSQLMS称为更改表而没有drop和create的一些压力,当你使用设计器改变字段类型时,你可以看到它是一个美丽的消息。我不明白为什么他们让你打开设计师并实际编辑字段类型如果最终你得到这样的操作消息不允许yadayadayada ...

如果有人知道更简单的方法就提到它,希望它有助于某人......

答案 5 :(得分:-2)

总体思路如下。别忘了先备份你的数据库。

ALTER TABLE tableName ADD tempColumn VARCHAR(5)

UPDATE tableName SET tempColumn = pkColumn

-- Do this for all constraints

ALTER TABLE tableName DROP CONSTRAINT pkConstraint

ALTER TABLE tableName DROP COLUMN pkColumn

ALTER TABLE tableName ADD pkColumn VARCHAR(5)

UPDATE tableName SET pkColumn = tempColumn

ALTER TABLE tableName DROP COLUMN tempColumn