SQL Azure'da mevcut bir Birincil Anahtar'ı nasıl değiştirebilirim?


25

SQL Azure tablosundaki varolan bir birincil anahtarı değiştirmek istiyorum.
Şu anda bir sütun var ve bir tane daha eklemek istiyorum.

Şimdi, SQL Server 2008'de bu bir parça kekdi, SSMS'de yaptım. Bitti. SQL Server'dan komut dosyası yazarsam PK şöyle görünür:

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

Ancak, SQL Azure'da yukarıdakileri çalıştırmaya çalıştığımda, elbette başarısız olacak:

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

Tamam, anahtarı bırakmaya çalışıyorum:

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

Tamam, PK'yi bırakmak için geçici bir kümelenmiş indeks oluşturmaya çalışıyorum:

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

Hangi sonuçlarla: Cannot create more than one clustered index on table 'Friend'. Drop the existing clustered index 'PK_Friend' before creating another.

Harika, catch22 anı.

UserId sütununu mevcut PK’ma nasıl eklerim?


Yanıtlar:


34

Not: Azure SQL Database v12'den itibaren bu kısıtlamalar artık geçerli değildir.

'Birincil endeks' gibi bir şey değil. 'Birincil anahtar' gibi bir şey var ve ayrıca 'kümelenmiş bir dizin' gibi bir şey var. Farklı kavramlar, çoğu zaman karıştı. Bu ayrım göz önüne alındığında, soruyu tekrar gözden geçirelim:

S1) SQL Azure tablosundaki kümelenmiş dizin değiştirilebilir mi?
A: Evet. Kullanım 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

S2) Birincil anahtar kısıtlaması olan bir tablonun kümelenmiş indeksi değiştirilebilir mi?
C: Evet, birincil anahtar kısıtlaması kümelenmiş dizin aracılığıyla uygulanmadığı sürece yukarıdakiyle aynı:

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

S3) Bir tablonun birincil anahtar kısıtı değiştirilebilir mi?
C: Evet, birincil kısıtlama kümelenmiş endeks üzerinden uygulanmadığı sürece:

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

S4) Bir tablonun ana anahtarı, kümelenmiş dizin üzerinden uygulandığında değiştirilebilir mi?
C: Evet, eğer masa hiç satır almamışsa:

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

S5) Tablo doldurulursa, kümelenmiş dizin üzerinden zorlandığında tablonun ana anahtarı değiştirilebilir mi?
C: Hayır. Doldurulmuş kümelenmiş bir dizini bir yığına dönüştüren herhangi bir işlem , tablo boş olsa bile , SQL Azure'da engellenir :

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;

Yan not olarak: tablo kesilirse kısıtlama değiştirilebilir .

Doldurulmuş bir tablonun PK kısıtlamasını değiştirmek için geçici çözüm, eski sp_renamenumarayı yapmaktır :

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_renameYaklaşım en önemlisi masaya izinleri yeniden adlandırma, hem de yabancı anahtar kısıtlamaları sırasında taşınmaz varlık, bazı sorunlar vardır.


A1-A4, benim durumumda cevap yok. Numaramı bir kimlik sütunu olmasa da A5 numarayı yaptı.
Magnus

sp_rename geçici çözümü yardımcı oldu!
Justin,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.