J'ai scénarisé une clé étrangère, et d'utiliser les tables sys
pour obtenir tous les détails que je dois reconstruire le script:
SELECT FK.[name]
--
,FK.[delete_referential_action_desc]
,FK.[update_referential_action_desc]
--
,KC.[constraint_column_id]
,PS.[name]
,P.[name]
,PTC.[name]
--
,RTS.[name]
,RT.[name]
,RTC.[name]
FROM [sys].[foreign_keys] FK
INNER JOIN [sys].[objects] P
ON FK.[parent_object_id] = P.[object_id]
INNER JOIN [sys].[schemas] PS
ON P.[schema_id] = PS.[schema_id]
INNER JOIN [sys].[foreign_key_columns] KC
ON FK.[object_id] = KC.[constraint_object_id]
-- parent columns
INNER JOIN [sys].[columns] PTC
ON P.[object_id] = PTC.[object_id]
AND KC.[parent_column_id] = PTC.[column_id]
-- referenced table schema, name and columns
INNER JOIN [sys].[objects] RT
ON KC.[referenced_object_id] = RT.[object_id]
INNER JOIN [sys].[schemas] RTS
ON RT.[schema_id] = RTS.[schema_id]
INNER JOIN [sys].[columns] RTC
ON RT.[object_id] = RTC.[object_id]
AND KC.[referenced_column_id] = RTC.[column_id];
Cela me donnera même les détails du schéma de chaque table. Maintenant, vous pouvez utiliser cette instruction T-SQL afin de faire ce que vous voulez. Remarque, je suis en train de l'emballage dans CTE
juste pour rendre les choses plus lisibles. En outre, nous avons la deuxième CTE
afin de gérer les situations où la clé étrangère est composée de plusieurs colonnes.
WITH DataSource AS
(
SELECT FK.[name] AS [FK_Name]
--
,FK.[delete_referential_action_desc]
,FK.[update_referential_action_desc]
--
,KC.[constraint_column_id] AS [FK_ColumnPos]
,PS.[name] AS [PT_SCHEMA_NAME]
,P.[name] AS [PT_NAME]
,PTC.[name] AS [PT_COLUMN_NAME]
--
,RTS.[name] AS [RF_SCHEMA_NAME]
,RT.[name] AS [RF_NAME]
,RTC.[name] AS [RF_COLUMN_NAME]
FROM [sys].[foreign_keys] FK
INNER JOIN [sys].[objects] P
ON FK.[parent_object_id] = P.[object_id]
INNER JOIN [sys].[schemas] PS
ON P.[schema_id] = PS.[schema_id]
INNER JOIN [sys].[foreign_key_columns] KC
ON FK.[object_id] = KC.[constraint_object_id]
-- parent columns
INNER JOIN [sys].[columns] PTC
ON P.[object_id] = PTC.[object_id]
AND KC.[parent_column_id] = PTC.[column_id]
-- referenced table schema, name and columns
INNER JOIN [sys].[objects] RT
ON KC.[referenced_object_id] = RT.[object_id]
INNER JOIN [sys].[schemas] RTS
ON RT.[schema_id] = RTS.[schema_id]
INNER JOIN [sys].[columns] RTC
ON RT.[object_id] = RTC.[object_id]
AND KC.[referenced_column_id] = RTC.[column_id]
), DataSourcePrecalc AS
(
SELECT DISTINCT
[FK_Name]
,[delete_referential_action_desc]
,[update_referential_action_desc]
,[PT_SCHEMA_NAME]
,[PT_NAME]
,STUFF
(
(
SELECT ', [' + DS1.[PT_COLUMN_NAME] + ']'
FROM DataSource DS1
WHERE DS1.[FK_Name] = DS.[FK_Name]
AND DS1.[PT_NAME] = DS.[PT_NAME]
ORDER BY DS1.[FK_ColumnPos]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,2
,''
) AS [PT_COLUMNS]
,[RF_SCHEMA_NAME]
,[RF_NAME]
,STUFF
(
(
SELECT ', [' + DS2.[RF_COLUMN_NAME] + ']'
FROM DataSource DS2
WHERE DS2.[FK_Name] = DS.[FK_Name]
AND DS2.[RF_NAME] = DS.[RF_NAME]
ORDER BY DS2.[FK_ColumnPos]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,2
,''
) AS [RT_COLUMNS]
FROM DataSource DS
)
SELECT
'
ALTER TABLE [' + [PT_SCHEMA_NAME] + '].[' + [PT_NAME] + '] DROP CONSTRAINT [' + [FK_Name] + '];
ALTER TABLE [' + [PT_SCHEMA_NAME] + '].[' + [PT_NAME] + '] WITH CHECK ADD CONSTRAINT [' + [FK_Name] + '] FOREIGN KEY(' + [PT_COLUMNS] + ')
REFERENCES [' + [RF_SCHEMA_NAME] + '].[' + [RF_NAME] + '] (' + [RT_COLUMNS] + ')
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE [' + [PT_SCHEMA_NAME] + '].[' + [PT_NAME] + '] CHECK CONSTRAINT [' + [FK_Name] + '];
'
FROM DataSourcePrecalc;
Notez ici les valeurs CASCADE
sont difficiles codded. Vous pouvez ajouter une autre logique si vous voulez, utilisez les originaux. Ce qui est plus important ici, c'est la requête initiale qui nous apporte tous les détails nécessaires. L'avoir, vous pouvez faire ce que vous voulez.