SQL Azure에서 기존 기본 키를 어떻게 변경합니까?


25

SQL Azure 테이블에서 기존 기본 키를 수정하고 싶습니다.
현재 하나의 열이 있으며 다른 열을 추가하고 싶습니다.

이제 SQL Server 2008에서 이것은 일종의 케이크였습니다. SSMS에서 그랬습니다. 끝난. SQL Server에서 PK를 스크립팅하면 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.

캐치 22의 순간.

기존 PK에 UserId 열을 어떻게 추가합니까?


답변:


34

참고 : Azure SQL Database v12부터는 이러한 제한이 더 이상 적용되지 않습니다.

'1 차 색인'과 같은 것은 없습니다. '기본 키'와 같은 것이 있으며 '클러스터형 인덱스'와 같은 것도 있습니다. 뚜렷한 개념, 종종 혼란. 이러한 차이점을 염두에두고 질문을 다시 살펴 보겠습니다.

Q1) SQL Azure 테이블의 클러스터형 인덱스를 수정할 수 있습니까?
A : 그렇습니다. 사용 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) 테이블의 기본 키 제약 조건을 수정할 수 있습니까?
A : 예. 클러스터 된 인덱스를 통해 기본 제약 조건이 적용되지 않는 한 :

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) 테이블이 채워져 있으면 클러스터형 인덱스를 통해 테이블을 적용 할 때 테이블의 기본 키를 수정할 수 있습니까?
A : 아니요. 채워진 클러스터형 인덱스를 힙으로 변환하는 작업 은 테이블이 비어 있어도 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접근 방식에는 몇 가지 문제가 있으며, 가장 중요한 것은 테이블에 대한 권한은 이름을 바꾸는 동안 외래 키 제약 조건을 수행하지 않는다는 것입니다.


A1-A4는 제 대답이 없습니다. 내 ID는 ID 열이 아니지만 A5가 트릭을 수행했습니다.
Magnus

sp_rename 대안이 도움이되었습니다!
저스틴
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.