Cambiar Primary Key NonClustered a Clustered en SQL SERVER

 Buenas tardes queridos lectores, regresamos a escribir acerca de SQL SERVER, y les plantearé el siguiente problema:



Cuando se creó una base de datos, crearon las llaves primarias como NonClustered, eso está correcto si vas a utilizar otro índice que sea Clustered, sin embargo, en este caso no hay indice clustered en la tabla, por lo que ahora se desea que la llave primaria ahora sea clustered, así que lo que tenemos que hacer el eliminar la llave primaria NonClustered, para después crearla nuevamente, pero ahora como Clustered.


Aquí nos encontraremos con un problema, que esa llave primaria, es llave foránea de otras tablas, por lo que tenemos que eliminar las llaves foráneas antes de eliminar la llave primaria. Pues bien, planteemos el escenario que nos ocupa. 

Consideremos la siguiente base de datos con sus respectivas tablas:

create database pruebas1

go


use pruebas1

go


create table alumnos

(id int identity,

nombre varchar(200),

apellidop varchar(200),

apellidom varchar(200),

constraint pk_alumnos_id primary key nonclustered (id))


create table materias

(id int identity,

nombre varchar(200),

constraint pk_materia_id primary key nonclustered (id)

)


create table clase

(

id int primary key identity,

nombre varchar(200),

alumno_id int,

materia_id int,

constraint fk_clase_alumno_id foreign key (alumno_id) references alumnos (id),

constraint fk_clase_materia_id foreign key (materia_id) references materias (id)

)



create table calificaciones

(id int primary key identity,

materia_id int,

alumno_id int,

calificacion decimal (4,2),

constraint fk_calificiones_alumno foreign key (alumno_id) references alumnos (id)

)


Ahora intentaremos cambiar la llave primaria constraint pk_alumnos_id primary key nonclustered (id)) de la tabla alumnos por una llave Clustered, así que procedemos a borrarla


alter table alumnos drop constraint pk_alumnos_id 

Y nos retornará el siguiente error:

Msg 3725, Level 16, State 0, Line 35

The constraint 'pk_alumnos_id' is being referenced by table 'calificaciones', foreign key constraint 'fk_calificiones_alumno'.

Msg 3727, Level 16, State 0, Line 35

Could not drop constraint. See previous errors.


Este error se debe a que esa llave primaria es una llave foránea en la tabla de calificaciones, pero puede no ser la única foreign key que exista, se deben de borrar todas las foreign key para porder eliminar la primary key, así que consideremos el siguiente script:


SELECT

f.name AS foreign_key_name

,OBJECT_NAME(f.parent_object_id) AS table_name

,COL_NAME(fc.parent_object_id, fc.parent_column_id) AS constraint_column_name

,OBJECT_NAME (f.referenced_object_id) AS referenced_object

,COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS referenced_column_name

,is_disabled

,delete_referential_action_desc

,update_referential_action_desc

, 'ALTER TABLE ' + OBJECT_NAME(f.parent_object_id) + ' DROP CONSTRAINT ' + f.name as eliminar

, 'ALTER TABLE ' + OBJECT_NAME(f.parent_object_id) + ' ADD ' + 'CONSTRAINT ' + f.name +

' foreign key ' + '(' + COL_NAME(fc.parent_object_id, fc.parent_column_id) + ') references ' +

OBJECT_NAME (f.referenced_object_id)+ ' (' + COL_NAME(fc.referenced_object_id, fc.referenced_column_id)+')'

FROM sys.foreign_keys AS f

INNER JOIN sys.foreign_key_columns AS fc

ON f.object_id = fc.constraint_object_id

WHERE f.referenced_object_id = OBJECT_ID('dbo.alumnos');


El resultado será el siguiente:



Como vemos, ahi estan las consultas para eliminar las foreign key y la otra columna para crear


--Eliminar restricciones

ALTER TABLE clase DROP CONSTRAINT fk_clase_alumno_id

ALTER TABLE calificaciones DROP CONSTRAINT fk_calificiones_alumno


Una vez eliminadas las restricciones, ahora si podremos eliminar la primary key

alter table alumnos drop constraint pk_alumnos_id 

Y luego la volvemos a crear

--crear clustered

alter table alumnos add constraint pk_alumnos_id primary key clustered (id)


Y ahora volvemos a poner las llaves foráneas


--Crear llaves foráneas

ALTER TABLE clase ADD CONSTRAINT fk_clase_alumno_id foreign key (alumno_id) references alumnos (id)

ALTER TABLE calificaciones ADD CONSTRAINT fk_calificiones_alumno foreign key (alumno_id) references alumnos (id)


Listo, ya tenemos nuestra primary key modificada como clustered


Espero que les haya sido de utilidad este post, los invito a que comenten, compartan o den clic a algún anuncio.


Saludos

No hay comentarios.:

Publicar un comentario

Featured Post

Como saber la versión de SQL que tengo

 Buenas tardes queridos lectores, el día de hoy les traigo un post muy básico, pero útil en determinadas circunstancias, cuando queremos sab...