【问题标题】:change primary key value更改主键值
【发布时间】:2018-03-01 23:35:55
【问题描述】:

我有 10 张桌子。每个表都被其他 5 个表的外键引用。

我需要更改这 10 个表的主键值。有什么办法可以改变它,让它自动改变所有的外键?

我使用的是 sql server 2008 并且有管理工作室。

【问题讨论】:

  • 只是出于好奇,你为什么要这样做?
  • @Abe Miessler:我必须更改数据库的结构。我想为这 10 个表创建一个超类型。

标签: sql sql-server sql-server-2008 primary-key


【解决方案1】:

这里是一个示例,您可以如何使用 ON UPDATE CASCADE 外键选项来完成此操作。您将感兴趣的部分是两个ALTER TABLE 语句。

如果您使用IDENTITY 列作为主键,那么这将变得更加困难,因为您无法更新IDENTITY 列。

CREATE TABLE Parent
(
    ParentId INT NOT NULL CONSTRAINT [PK_Parent] PRIMARY KEY CLUSTERED,
    Name VARCHAR(10) NOT NULL
)

CREATE TABLE Child 
(
  ChildId INT NOT NULL CONSTRAINT [PK_Child] PRIMARY KEY CLUSTERED,
  ParentId INT NOT NULL CONSTRAINT [FK_Child_ParentId] FOREIGN KEY REFERENCES Parent (ParentId),
  Name VARCHAR(10) NOT NULL
)

INSERT INTO Parent (ParentId, Name) VALUES (1, 'Bob')
INSERT INTO Parent (ParentId, Name) VALUES (2, 'Sue')

INSERT INTO Child (ChildId, Name, ParentId) VALUES (1, 'Alice', 1)
INSERT INTO Child (ChildId, Name, ParentId) VALUES (2, 'Billy', 2)

SELECT * FROM Child 

-- Drop foreign key constraint and re-add 
ALTER TABLE Child 
  DROP CONSTRAINT [FK_Child_ParentId]

ALTER TABLE Child
 ADD CONSTRAINT [FK_Child_ParentId] 
    FOREIGN KEY (ParentId) REFERENCES Parent (ParentId) ON UPDATE CASCADE 

UPDATE Parent SET ParentId = ParentId + 100 

SELECT * FROM Child --shows the new ParentIds 

DROP TABLE Child 
DROP TABLE Parent 

【讨论】:

  • 完成后,可能值得将约束更新回不支持级联更新。
  • @Chris Diver:我知道!我有标识列,所以我为每个表所做的是: 1. 创建 new_id 列。 2.设置new_id为新id。 3. 删除约束。 4. 使用 new_id 更新了引用。 5.删除主键。 6. 删除旧的 id 列。 7. 使用 new_id 创建新的主键。 8.将new_id重命名为id。 9. 再次创建约束。我希望避免这一切。我正在寻找一个允许自动更新主键及其引用的命令,因为我有 10 个表要走。
  • 您应该在问题中更清楚地说明您的要求。在那种情况下,我用you can't update an IDENTITY column 回答了你的问题。因此,您不能“自动”执行此操作。但是您可以重新使用用于创建新列等的相同 T-SQL...并将表名和列名指定为变量。
【解决方案2】:

您需要为这些外键设置 ON UPDATE CASCADE:

ALTER TABLE bar
ADD CONSTRAINT FK_foo_bar
FOREIGN KEY (fooid) REFERENCES foo(id)
ON UPDATE CASCADE

然后您只需更新 FK,引用字段也将作为交易的一部分进行更新:

UPDATE foo SET id = id + 1000

请注意,要更改约束,需要删除它们。

【讨论】:

  • UPDATE CASCADE 是否会自动更改包含引用的表中的 FK 字段?
【解决方案3】:

我自己从来没有这样做过,听起来这可能是个坏主意。也就是说,我确实找到了这篇文章,其中介绍了两种方法:

http://support.microsoft.com/kb/142480

一个使用存储过程和其他触发器。两者似乎都有点痛苦。

【讨论】:

  • 我不是在寻找通过单击按钮定期执行此操作的代码。为了修复我的数据库方案,这只是一次更改。
【解决方案4】:

IDENTITY 列的一个显着缺点是不能直接更新。

解决方法是不在目标表中使用 IDENTITY,而是将其放在额外的表中。先插入到具有 IDENTITY 列的表中,然后将生成的 IDENTITY 值插入到目标表中。

SQL Server 2012 引入了独立于表的序列,这是解决同一问题的更好方法。序列不需要额外的表格。

【讨论】:

    【解决方案5】:

    我知道这并不是您问题的真正答案,但我是在寻找如何简单地设置(写入、插入、更新或其他)PK(主键)列时来到这里的。

    所以你必须禁用 PK 约束,插入你的值,然后再启用它,更新将不起作用。

    SET IDENTITY_INSERT IdentityTable ON
    INSERT IdentityTable(TheIdentity, TheValue) VALUES (3, 'First Row')
    SET IDENTITY_INSERT IdentityTable OFF
    

    【讨论】:

      猜你喜欢
      • 2020-09-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多