AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 6937
Accepted
Magnus
Magnus
Asked: 2011-10-19 10:21:54 +0800 CST2011-10-19 10:21:54 +0800 CST 2011-10-19 10:21:54 +0800 CST

如何更改 SQL Azure 上的现有主键?

  • 772

我想修改 SQL Azure 表上的现有主键。
它目前有一列,我想添加另一列。

现在,在 SQL Server 2008 上,这是小菜一碟,只是在 SSMS 中做到了,噗。完毕。如果我从 SQL Server 编写脚本,这就是 PK 的样子:

ALTER TABLE [dbo].[Friend] ADD  CONSTRAINT [PK_Friend] PRIMARY KEY CLUSTERED 
(
  [UserId] ASC,
  [Id] ASC
)

但是,在 SQL Azure 上,当我尝试执行上述操作时,它当然会失败:

Table 'Friend' already has a primary key defined on it.

好的,所以我尝试删除密钥:

Tables without a clustered index are not supported in this version of SQL Server. Please create a clustered index and try again.

好的,所以我尝试创建一个临时聚集索引以删除 PK:

CREATE CLUSTERED INDEX IX_Test ON [Friend] ([UserId],[Id])

结果是: Cannot create more than one clustered index on table 'Friend'. Drop the existing clustered index 'PK_Friend' before creating another.

太好了,一个 catch22 时刻。

如何将 UserId 列添加到我现有的 PK?

primary-key azure-sql-database
  • 1 1 个回答
  • 15886 Views

1 个回答

  • Voted
  1. Best Answer
    Remus Rusanu
    2011-10-19T13:38:00+08:002011-10-19T13:38:00+08:00

    注意:从 Azure SQL 数据库 v12 开始,这些限制不再适用。

    这不是“主要索引”之类的东西。有“主键”之类的东西,也有“聚集索引”之类的东西。不同的概念,经常混淆。考虑到这种区别,让我们重新审视这个问题:

    Q1) 可以修改 SQL Azure 表中的聚集索引吗?
    答:是的。使用 WITH (DROP_EXISTING=ON):

    create table Friend (
        UserId int not null,
        Id int not null);
    go  
    create clustered index cdxFriend on Friend (UserId, Id);
    go
    create clustered index cdxFriend on Friend (Id, UserId) with (drop_existing=on);
    go
    

    Q2) 有主键约束的表的聚集索引可以修改吗?
    A:是的,和上面一样,只要不通过聚集索引强制执行主键约束:

    create table Friend (
        UserId int not null,
        Id int not null identity(1,1),
        constraint pk_Friend primary key nonclustered (Id));
    create clustered index cdxFriend on Friend (UserId, Id);
    go
    create clustered index cdxFriend on Friend (Id, UserId) with (drop_existing=on);
    go
    

    Q3) 可以修改表的主键约束吗?
    答:可以,只要不通过聚集索引强制执行主约束:

    create table Friend (
        UserId int not null,
        Id int not null identity(1,1),
        constraint pk_Friend primary key nonclustered (Id));
    go
    create clustered index cdxFriend on Friend (UserId, Id);
    go
    alter table Friend drop constraint pk_Friend;
    alter table Friend add constraint pk_Friend primary key nonclustered (UserId)
    go
    

    Q4) 通过聚集索引强制执行时,可以修改表的主键吗?
    A:是的,如果表从未有任何行:

    create table Friend (
        UserId int not null,
        Id int not null identity(1,1),
        constraint pk_Friend primary key clustered (UserId, Id));
    go
    alter table Friend drop constraint pk_Friend;
    alter table Friend add constraint pk_Friend primary key clustered (Id, UserId)
    go
    

    Q5) 如果表格被填充,可以通过聚集索引强制修改表格的主键吗?
    答:不可以。任何将填充的聚集索引转换为堆的操作都将在 SQL Azure 中被阻止,即使表为空:

    create table Friend (
        UserId int not null,
        Id int not null identity(1,1),
        constraint pk_Friend primary key clustered (UserId, Id));
    go
    insert into Friend (UserId) values (1);
    delete from Friend;
    go
    alter table Friend drop constraint pk_Friend;
    

    附带说明:如果表被截断,则可以修改约束。

    更改填充表的 PK 约束的解决方法是使用旧sp_rename技巧:

    create table Friend (
        UserId int not null,
        Id int not null identity(1,1),
        constraint pk_Friend primary key clustered (UserId, Id));
    go
    insert into Friend (UserId) values (1);
    go
    
    create table FriendNew (
        UserId int not null,
        Id int not null identity(1,1),
        constraint pk_Friend_New primary key clustered (Id, UserId));
    go
    
    set identity_insert FriendNew on;
    insert into FriendNew (UserId, Id) 
    select UserId, Id
    from Friend;
    set identity_insert FriendNew off;
    go
    
    begin transaction
    exec sp_rename 'Friend', 'FriendOld';
    exec sp_rename 'FriendNew', 'Friend';
    commit;
    go
    
    sp_help 'Friend';
    

    该sp_rename方法存在一些问题,最重要的是表的权限在重命名期间不会继承,以及外键约束。

    • 34

相关问题

  • 为什么使用 int 作为查找表的主键?

  • 包含表的所有列的主键有什么好处吗?

  • 从复合键中删除字段并整理重复数据

  • 使用 UUID 或 GUID 作为主键有什么缺点?

  • 字符与整数主键

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve