SQL Server:重命名主键

21

我有一个名为doc.MyTable的表格,我想通过重命名为doc._MyTable来使其过时。然后,我想创建一个新的doc.MyTable,并拥有与旧的doc.MyTable相同的主键。但问题是SQL Server表示该主键已经存在。这意味着我还需要重命名旧的主键。

我尝试了以下操作:

EXEC SP_RENAME 'doc.MyTable', '_MyTable'

-- Method 1
EXEC SP_RENAME 'PK_MyTable', 'PK__MyTable'

-- Method 2
ALTER TABLE [doc].[_MyTable] DROP CONSTRAINT [PK_MyTable]
ALTER TABLE [doc].[_MyTable] ADD CONSTRAINT [PK__MyTable]
PRIMARY KEY CLUSTERED
(
    [document_id] ASC,
    [line_id] ASC,
    [sub_line_id] ASC
)

-- Create new table
CREATE TABLE [doc].[MyTable] (
    ... columns
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED (
    ... key columns
)
... extra conditions

方法1抛出以下错误:

在当前数据库“db_dev”中找不到名称为“PK_MyTable”的项目,因为输入的@itemtype为“(null)”。

而方法2则抛出以下错误:

违反主键约束条件“PK_MyTable”。无法在对象“PK.MyTable”中插入重复键。
重复键值为(10358930,336000,0)。

当我尝试为新表创建新的主键时。

我每次只使用其中一种“方法”。如何解决这个问题?


方法1和方法2不清楚。 - paparazzo
这里的“Methods”是指上面代码中的“tries”。我将其全部改为“Method”,以使其更加清晰明了。 - user3685285
3个回答

22

尝试以下解决方案:

EXEC sp_rename '[TableSchema].[TableName].[ConstraintName]', 'NewConstraintName'

例子:

EXEC sp_rename '[doc].[_MyTable].[PK_MyTable]', '[PK__MyTable]'

2
当重命名主键时,应该像这样在主键名称前缀中加上模式和表名:
create schema doc authorization dbo;
go
create table doc.MyTable (
    id int not null
  , constraint pk_MyTable primary key clustered (Id)
);
exec sp_rename N'doc.MyTable.pk_MyTable', N'pk__MyTable';
exec sp_rename N'doc.MyTable', N'_MyTable', N'object';
create table doc.MyTable (
    id int not null
  , constraint pk_MyTable primary key clustered (Id)
);

rextester演示:http://rextester.com/OBIB87116

如果您使用默认模式dbo,则不需要在使用sp_rename重命名主键时添加模式和表名前缀。


你不需要使用 N'[_MyTable]',这会创建一个名为 [[_MyTable]] 的表。只需使用 '_MyTable' 即可。 _MyTable 无需转义,你可以写成 select * from doc._MyTable - Panagiotis Kanavos
@PanagiotisKanavos 已经纠正。 - SqlZim

-3

你不能从原始表中删除它,然后使用你想要的名称重新创建它吗?

ALTER TABLE dbo.YourOldTable
DROP CONSTRAINT YourConstraintname;   

这应该是一条注释,而不是一个回答。此外,sp_rename 没有任何问题。 - Panagiotis Kanavos
我并没有说一定要这样做。删除索引并使用不同的名称进行读取是完全有效的,甚至可以说是更好的答案。 - GandRalph
2
实际上这是一个非常糟糕和昂贵的解决方案。它意味着索引必须进行重建,这是一个非常昂贵的操作。主键通常是聚集索引,这意味着整个表必须转换为堆然后再转换为聚集索引结构。 - Panagiotis Kanavos
这不是和我第二次尝试一样吗? - user3685285
@user3685285 的回答是正确的。如果你使用除了 dbo 以外的模式,你必须使用三部分名称,即 schema.table.name - Panagiotis Kanavos

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