Hinweis: Ab Azure SQL Database v12 gelten diese Einschränkungen nicht mehr.
Das ist kein Primärindex. Es gibt so etwas wie einen "Primärschlüssel" und es gibt auch so etwas wie einen "Clustered Index". Eindeutige Konzepte, oft verwirrt. In Anbetracht dieser Unterscheidung lassen Sie uns die Frage noch einmal betrachten:
F1) Kann der Clustered-Index in einer SQL Azure-Tabelle geändert werden?
A: Ja. Verwendung 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
F2) Kann der Clustered-Index einer Tabelle mit einer Primärschlüsseleinschränkung geändert werden?
A: Ja, genau wie oben, solange die Primärschlüsseleinschränkung nicht über den Clustered-Index erzwungen wird:
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
F3) Kann die Primärschlüsselbedingung einer Tabelle geändert werden?
A: Ja, solange die primäre Einschränkung nicht über den Clustered-Index erzwungen wird:
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
F4) Kann der Primärschlüssel einer Tabelle geändert werden, wenn er über den Clustered-Index erzwungen wird?
A: Ja, wenn die Tabelle keine Zeilen hatte:
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
F5) Kann der Primärschlüssel einer Tabelle geändert werden, wenn er über den Clustered-Index erzwungen wird, wenn die Tabelle gefüllt ist?
A: Nein. Alle Vorgänge, die einen aufgefüllten Clustered-Index in einen Heap konvertieren, werden in SQL Azure blockiert, auch wenn die Tabelle leer ist :
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;
Als Randnotiz: Die Einschränkung kann geändert werden, wenn die Tabelle abgeschnitten ist .
Die Problemumgehung zum Ändern der PK-Einschränkung einer aufgefüllten Tabelle besteht darin, den guten alten sp_rename
Trick auszuführen:
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';
Der sp_rename
Ansatz weist einige Probleme auf, insbesondere, dass Berechtigungen für die Tabelle beim Umbenennen nicht übertragen werden, sowie Einschränkungen für Fremdschlüssel.