Nota: a partir de Azure SQL Database v12, estas restricciones ya no se aplican.
El no existe como un 'índice primario'. Existe una 'clave primaria' y también existe un 'índice agrupado'. Conceptos distintos, a menudo confundidos. Con esta distinción en mente, volvamos a la pregunta:
Q1) ¿Se puede modificar el índice agrupado en una tabla SQL Azure?
A: si. Uso 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
P2) ¿Se puede modificar el índice agrupado de una tabla que tiene una restricción de clave primaria?
R: Sí, igual que el anterior, siempre que la restricción de clave principal no se aplique a través del índice agrupado:
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
P3) ¿Se puede modificar la restricción de clave principal de una tabla?
R: Sí, siempre que la restricción primaria no se aplique a través del índice agrupado:
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
P4) ¿Se puede modificar la clave primaria de una tabla cuando se aplica a través del índice agrupado?
A: Sí, si la tabla nunca tuvo filas:
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
P5) ¿Se puede modificar la clave primaria de una tabla cuando se aplica a través del índice agrupado si la tabla está llena?
R: No. Cualquier operación que convierta un índice agrupado poblado en un montón se bloqueará en SQL Azure, incluso si la tabla está vacía :
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;
Como nota al margen: la restricción se puede modificar si la tabla se trunca .
La solución alternativa para cambiar la restricción PK de una tabla poblada es hacer el viejo sp_rename
truco:
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';
El sp_rename
enfoque tiene algunos problemas, lo más importante es que los permisos en la tabla no se transfieren durante el cambio de nombre, así como las restricciones de clave externa.