所以我需要重新创建一堆外键。原因是我想添加级联到密钥,并且为此我需要删除并重新创建密钥。当然,我可以通过右键单击密钥 - >修改 - >并添加级联来实现。 但我有索姆100键,我想在脚本中做到这一点。tsql得到fk_key规范
我有一个想法,我应该能够调用ssms中的方法,将该脚本的脚本脚本编写到新的查询编辑器中,而是将生成的脚本推送到变量中。放下现有的密钥。更新密钥的字符串表示形式,然后执行动态sql来创建它。
虽然我无法编写密钥脚本。 有谁知道如何做到这一点或有其他的方法吗?
所以我需要重新创建一堆外键。原因是我想添加级联到密钥,并且为此我需要删除并重新创建密钥。当然,我可以通过右键单击密钥 - >修改 - >并添加级联来实现。 但我有索姆100键,我想在脚本中做到这一点。tsql得到fk_key规范
我有一个想法,我应该能够调用ssms中的方法,将该脚本的脚本脚本编写到新的查询编辑器中,而是将生成的脚本推送到变量中。放下现有的密钥。更新密钥的字符串表示形式,然后执行动态sql来创建它。
虽然我无法编写密钥脚本。 有谁知道如何做到这一点或有其他的方法吗?
我已经脚本外键,并使用sys
表来获取我需要重建该脚本的所有细节:
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];
这会给我甚至每个表的架构细节。现在,你可以使用这个T-SQL语句来做你想做的事情。请注意,我正在使用CTE
来包装它,只是为了让这些东西更具可读性。此外,我们还有第二个CTE
以处理外键由多列组成的情况。
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;
注意,这里的CASCADE
值硬codded。你可以添加一些其他的逻辑,如果你想使用原来的。这里最重要的是最初的查询,它为我们带来了所有需要的细节。拥有它,你可以做任何你想做的事情。