Dans le même contexte que la reconstruction d’indexes mentionnée ici, voici le script complémentaire lié à la reconstruction de clés primaires. Etant donné qu’il n’existe pas de syntaxe permettant que créer une contrainte de clé étrangère en mode « remplacement », je présenterai ci-dessous un script générant la suppression des contraintes de clé primaire, et un script permettant de les régénérer.
Voici donc un premier script assez simple pour supprimer toutes les contraintes de clé primaire.
-- Générateur de script de suppressions de clés primaires -- Auteur : Jean-Nicolas BERGER (www.sqlserver.fr) select 'ALTER TABLE '+quotename(s.name)+'.'+quotename(t.name)+' DROP CONSTRAINT '+ quotename(i.name) +';' from sys.tables t join sys.schemas s on s.schema_id=t.schema_id join sys.indexes i on i.object_id=t.object_id where i.is_primary_key=1
Mais avant de supprimer les contraintes, il ne faut pas oublier de préparer un script pour les régénérer…
-- Générateur de script de création de clés primaires
-- Auteur : Jean-Nicolas BERGER (www.sqlserver.fr)
set nocount on
-- Déclaration de variables
declare @Liste table (index_id int,
object_id int,
DebutCreate varchar(max),
FinCreate varchar(max),
ListeColonnes varchar(max))
declare @index_id int,@object_id int
declare @ListeColonnes varchar(max)
-- Index à prendre en compte, avec mise en place des paramètres
insert into @Liste(index_id,object_id,DebutCreate,FinCreate)
select i.index_id,t.object_id,
'ALTER TABLE ' +QUOTENAME(s.name)+'.'+QUOTENAME(t.name)+' ADD CONSTRAINT '
+ QUOTENAME(i.name) + ' PRIMARY KEY '+
+ case when i.index_id=1 then 'CLUSTERED ' else 'NONCLUSTERED ' end
+ ' (',
+') WITH ('
+ 'PAD_INDEX=' + case when i.is_padded=1 then 'ON' else 'OFF' end
+ ',FILLFACTOR = ' + convert(varchar,case when i.fill_factor=0 then 100 else i.fill_factor end)
+ ',SORT_IN_TEMPDB = ON'
+ ',IGNORE_DUP_KEY = ' + case when i.ignore_dup_key=1 then 'ON' else 'OFF' end
+ ',ALLOW_ROW_LOCKS = ' + case when i.allow_row_locks=1 then 'ON' else 'OFF' end
+ ',ALLOW_PAGE_LOCKS = ' + case when i.allow_page_locks=1 then 'ON' else 'OFF' end
+') ON '+QUOTENAME(ds.name)
+case when ds.type='PS' then '('+QUOTENAME(cp.name)+')' else '' end
from sys.indexes i
join sys.tables t on t.object_id=i.object_id
join sys.schemas s on s.schema_id=t.schema_id
join sys.data_spaces ds on ds.data_space_id=i.data_space_id
left join sys.index_columns icp on icp.object_id=i.object_id
and icp.index_id=i.index_id
and icp.partition_ordinal=1
left join sys.columns cp on cp.object_id=t.object_id
and cp.column_id=icp.column_id
where i.is_primary_key=1 and t.type='U'
-- Pour chaque PK
DECLARE curseur CURSOR FOR
SELECT index_id,object_id
FROM @Liste
OPEN curseur
FETCH NEXT FROM curseur INTO @index_id,@object_id
WHILE @@FETCH_STATUS = 0
BEGIN
-- Construction de la liste des colonnes de la clé primaire
SELECT @ListeColonnes=','
SELECT @ListeColonnes+=quotename(c.name)+case when ic.is_descending_key=1 then ' DESC' else ' ASC' end+','
FROM sys.index_columns ic
join sys.columns c on c.object_id=ic.object_id
and c.column_id=ic.column_id
where ic.object_id=@object_id
and ic.index_id=@index_id
and ic.key_ordinal>0
order by key_ordinal
-- Mise en forme de la liste de colonnes
SELECT @ListeColonnes=SUBSTRING(@ListeColonnes,2,len(@ListeColonnes)-2)
update @Liste
set ListeColonnes=@ListeColonnes
where object_id=@object_id
and index_id=@index_id
FETCH NEXT FROM curseur INTO @index_id,@object_id
END
CLOSE curseur
DEALLOCATE curseur
-- Présentation du résultat final
select DebutCreate + ListeColonnes + FinCreate +';' from @Liste
N’hésitez pas à me faire part de vos remarques…
Ping : Régénérer les clés étrangères | SQLServer.fr