2017-10-18 38 views
0

所以我需要重新創建一堆外鍵。原因是我想添加級聯到密鑰,並且爲此我需要刪除並重新創建密鑰。當然,我可以通過右鍵單擊密鑰 - >修改 - >並添加級聯來實現。 但我有索姆100鍵,我想在腳本中做到這一點。tsql得到fk_key規範

我有一個想法,我應該能夠調用ssms中的方法,將該腳本的腳本腳本編寫到新的查詢編輯器中,而是將生成的腳本推送到變量中。放下現有的密鑰。更新密鑰的字符串表示形式,然後執行動態sql來創建它。

雖然我無法編寫密鑰腳本。 有誰知道如何做到這一點或有其他的方法嗎?

回答

0

Aaron Bertrand的article描述了這一點,它將爲您完成這項工作。

它動態創建@create@drop sql查詢。您只需要更改創建腳本,讓你在@create查詢的這部分添加'on delete cascade'

FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 1, N'') + ') 
ON DELETE CASCADE;' 

它會刪除並重新創建你的數據庫的每個表的每個外鍵。

確保在執行它們之前檢查生成的查詢。

你可以嘗試一個工作版本here,Rextester已經有一個模式和一些表已經可以看到結果。

0

我已經腳本外鍵,並使用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。你可以添加一些其他的邏輯,如果你想使用原來的。這裏最重要的是最初的查詢,它爲我們帶來了所有需要的細節。擁有它,你可以做任何你想做的事情。