2012-05-19 54 views
6

我有很多表的數據庫,我要重命名的主/外鍵,索引和默認的約束根據以下規則:實現了鍵,索引,約束的命名標準

  • 主鍵:PK_<table name>
  • 外鍵:FK_<table_name>_<column name1>_column name2>...
  • 指標:IX_<table_name>_<column name1>_column name2>...
  • 默認約束:DF_<table_name>_<column name>
  • ç heck約束條件:CK_<table_name>_<column name>

有人已經完成了一個類似的SQL腳本?

+0

您可以指定更多的規則,例如如果您的索引被過濾或具有INCLUDE列,那麼您是否也要指定這些列,或者只是鍵列?檢查約束和唯一約束呢? –

+0

不能說我有,但我從來沒有使用GUI來創建東西,我總是在腳本中給我的東西名稱。你可以做上面的事情,但我認爲編寫數據庫並編輯它以獲得你想要的內容比編制上述內容更容易。 –

+0

另一個想法是如何處理名稱中帶下劃線的對象。在'Document_Folder'有一個名爲'Folder_Name'的列被'Document's'Folder_Name'列引用的情況下,讀取外鍵的對象名稱會非常令人困惑。 'FK_Document_Folder_Name_Document_Folder_Folder_Name'?我不確定這比系統生成的名稱'FK__Document__Docum__1DE57479'更有用... –

回答

8

要重命名主鍵簡單地PK_TableName

CREATE PROCEDURE dbo.Rename_PrimaryKeys 
    @PrintOnly BIT = 1 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @sql NVARCHAR(MAX); 
    SET @sql = N''; 

    SELECT @sql = @sql + CHAR(13) + CHAR(10) + 'EXEC sp_rename ''' 
     + REPLACE(name, '''', '''''') + ''', ''PK_' 
     + REPLACE(OBJECT_NAME(parent_object_id), '''', '') + ''', ''OBJECT'';' 
    FROM sys.key_constraints 
    WHERE type = 'PK' 
    AND name <> 'PK_' + REPLACE(OBJECT_NAME(parent_object_id), '''', '') 
    AND OBJECTPROPERTY(parent_object_id, 'IsMsShipped') = 0; 

    PRINT @sql; 

    IF @PrintOnly = 0 AND @sql > N'' 
    BEGIN 
     EXEC sp_executesql @sql; 
    END 
END 
GO 

同意這項計劃FK_TableName_col_col_ReferencedName_col_col重命名FKS:

CREATE PROCEDURE dbo.Rename_ForeignKeys_WithColumns 
    @PrintOnly BIT = 1 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @sql NVARCHAR(MAX); 
    SET @sql = N''; 

    SELECT @sql = @sql + CHAR(13) + CHAR(10) 
    + 'EXEC sp_rename ''' + REPLACE(name, '''', '''''') 
     + ''', ''FK_' + REPLACE(OBJECT_NAME(fk.parent_object_id), '''', '') 
    + '_' + STUFF((SELECT '_' + REPLACE(c.name, '''', '') 
     FROM sys.columns AS c 
      INNER JOIN sys.foreign_key_columns AS fkc 
      ON fkc.parent_column_id = c.column_id 
      AND fkc.parent_object_id = c.[object_id] 
     WHERE fkc.constraint_object_id = fk.[object_id] 
     ORDER BY fkc.constraint_column_id 
     FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '') 
    + '_' + REPLACE(OBJECT_NAME(fk.referenced_object_id), '''', '') 
    + '_' + STUFF((SELECT '_' + REPLACE(c.name, '''', '') 
     FROM sys.columns AS c 
      INNER JOIN sys.foreign_key_columns AS fkc 
      ON fkc.referenced_column_id = c.column_id 
      AND fkc.referenced_object_id = c.[object_id] 
     WHERE fkc.constraint_object_id = fk.[object_id] 
     ORDER BY fkc.constraint_column_id 
     FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '') 
     + ''', ''OBJECT'';' 
    FROM sys.foreign_keys AS fk 
    WHERE OBJECTPROPERTY(parent_object_id, 'IsMsShipped') = 0; 

    PRINT @sql; 

    IF @PrintOnly = 0 AND @sql > N'' 
    BEGIN 
     EXEC sp_executesql @sql; 
    END 
END 
GO 

外鍵,如果你只是想FK_TableName_ReferencedName那麼它是一個簡單多了:

CREATE PROCEDURE dbo.Rename_ForeignKeys 
    @PrintOnly BIT = 1 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @sql NVARCHAR(MAX); 
    SET @sql = N''; 

    SELECT @sql = @sql + CHAR(13) + CHAR(10) + 'EXEC sp_rename ''' 
     + REPLACE(name, '''', '''''') + ''', ''FK_' 
     + REPLACE(OBJECT_NAME(parent_object_id), '''', '') 
     + '_' + REPLACE(OBJECT_NAME(referenced_object_id), '''', '') 
     + ''', ''OBJECT'';' 
    FROM sys.foreign_keys 
    WHERE OBJECTPROPERTY(parent_object_id, 'IsMsShipped') = 0; 

    PRINT @sql; 

    IF @PrintOnly = 0 AND @sql > N'' 
    BEGIN 
     EXEC sp_executesql @sql; 
    END 
END 
GO 

對於指標,這將重命名任何我索引IX_TableName_Col1_Col2...。它會忽略主鍵(因爲它們在上面單獨處理),將添加UQ_到唯一索引/約束(因此IX_UQ_TableName_Col1_Col2...,將把唯一約束和唯一索引視爲相同,並且將忽略包含的列(注意,忽略包含的列可能會生產,如果你有多餘的指標,只有包含的列不同的命名衝突)

CREATE PROCEDURE dbo.Rename_Indexes 
    @PrintOnly BIT = 1 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @sql NVARCHAR(MAX); 
    SET @sql = N''; 

    SELECT @sql = @sql + CHAR(13) + CHAR(10) 
     + 'EXEC sp_rename ''' + REPLACE(i.name, '''', '''''') 
     + ''', ''IX_' + CASE is_unique_constraint WHEN 1 THEN 'UQ_' ELSE '' END 
     + REPLACE(OBJECT_NAME(i.[object_id]), '''', '') 
     + '_' + STUFF((SELECT '_' + REPLACE(c.name, '''', '') 
      FROM sys.columns AS c 
       INNER JOIN sys.index_columns AS ic 
       ON ic.column_id = c.column_id 
       AND ic.[object_id] = c.[object_id] 
      WHERE ic.[object_id] = i.[object_id] 
      AND ic.index_id = i.index_id 
      AND is_included_column = 0 
      ORDER BY ic.index_column_id 
      FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '') 
     +''', ''OBJECT'';' 
    FROM sys.indexes AS i 
    WHERE index_id > 0 
    AND is_primary_key = 0 -- dealt with separately 
    AND OBJECTPROPERTY(i.[object_id], 'IsMsShipped') = 0; 

    PRINT @sql; 

    IF @PrintOnly = 0 AND @sql > N'' 
    BEGIN 
     EXEC sp_executesql @sql; 
    END 
END 
GO 

對於默認約束:

CREATE PROCEDURE dbo.Rename_DefaultConstraints 
    @PrintOnly BIT = 1 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @sql NVARCHAR(MAX); 
    SET @sql = N''; 

    SELECT @sql = @sql + CHAR(13) + CHAR(10) 
     + 'EXEC sp_rename ''' + REPLACE(dc.name, '''', '''''') 
     + ''', ''DF_' + REPLACE(OBJECT_NAME(dc.parent_object_id), '''','') 
     + '_' + REPLACE(c.name, '''', '') + ''', ''OBJECT'';' 
    FROM sys.default_constraints AS dc 
    INNER JOIN sys.columns AS c 
    ON dc.parent_object_id = c.[object_id] 
    AND dc.parent_column_id = c.column_id 
    AND OBJECTPROPERTY(dc.parent_object_id, 'IsMsShipped') = 0; 

    PRINT @sql; 

    IF @PrintOnly = 0 AND @sql > N'' 
    BEGIN 
     EXEC sp_executesql @sql; 
    END 
END 
GO 

最後檢查約束:

CREATE PROCEDURE dbo.Rename_CheckConstraints 
    @PrintOnly BIT = 1 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @sql NVARCHAR(MAX); 
    SET @sql = N''; 

    SELECT @sql = @sql + CHAR(13) + CHAR(10) 
     + 'EXEC sp_rename ''' + REPLACE(cc.name, '''', '''''') 
     + ''', ''CK_' + REPLACE(OBJECT_NAME(cc.parent_object_id), '''','') 
     + '_' + REPLACE(c.name, '''', '') + ''', ''OBJECT'';' 
    FROM sys.check_constraints AS cc 
    INNER JOIN sys.columns AS c 
    ON cc.parent_object_id = c.[object_id] 
    AND cc.parent_column_id = c.column_id 
    AND OBJECTPROPERTY(dc.parent_object_id, 'IsMsShipped') = 0; 

    PRINT @sql; 

    IF @PrintOnly = 0 AND @sql > N'' 
    BEGIN 
     EXEC sp_executesql @sql; 
    END 
END 
GO 

注意PRINT不一定會揭示整個語句,這取決於你在文本和語句的大小結果設置。但它應該足以讓眼睛看到腳本正在做正確的工作。我默認將它們全部設置爲PrintOnly

+0

謝謝亞倫,我總是會用你的答案學習一些新東西。 – psadac

2

並重新命名的外鍵,你可以使用這樣的事情(這還沒有做正是你想要的東西 - 但足夠接近上手就可以了):基本上

DECLARE RenameFKCursor CURSOR FAST_FORWARD 
FOR 
    SELECT 
     'dbo.sp_rename @objName = ''' + fk.Name + ''', @NewName = ''FK_' + t.Name + '_' + ref.Name + ''', @objtype = ''OBJECT''' 
    FROM 
     sys.foreign_keys fk 
    INNER JOIN 
     sys.tables t ON fk.parent_object_id = t.object_id 
    INNER JOIN 
     sys.tables ref ON fk.referenced_object_id = ref.object_id 
    WHERE 
     fk.is_system_named = 1 

DECLARE @RenameFKStmt NVARCHAR(500) 

OPEN RenameFKCursor 

FETCH NEXT FROM RenameFKCursor INTO @RenameFKStmt 

WHILE (@@fetch_status <> -1) 
BEGIN 
    IF (@@fetch_status <> -2) 
    BEGIN 
     PRINT @RenameFKStmt 
     EXEC(@RenameFKStmt) 
    END 

    FETCH NEXT FROM RenameFKCursor INTO @RenameFKStmt 
END 

CLOSE RenameFKCursor 
DEALLOCATE RenameFKCursor 
GO 

,你遍歷數據庫中定義的所有外鍵,然後將它們重命名爲您決定如何在作爲此遊標基礎的SELECT中構造的某個名稱。

然後你運行光標放在所有結果,並執行dbo.sp_rename存儲過程來重命名爲任何你想他們是你的FK約束。

使用Aaron的方法只是基本上構建一個巨大的SQL語句,您甚至可以不必使用遊標就可以離開。

這將是非常類似的代碼,用於將「系統命名的」默認約束重命名爲您自己的命名約定 - 它使用與上述相同的方法,針對系統目錄視圖的SELECT,然後用於迭代所有條目,並建立和執行SQL語句重命名:

DECLARE DFCursor CURSOR FAST_FORWARD 
FOR 
    SELECT 
     dc.Name, 
     t.Name, 
     c.Name 
    FROM 
     sys.default_constraints dc 
    INNER JOIN 
     sys.tables t ON dc.parent_object_id = t.object_id 
    INNER JOIN 
     sys.columns c ON dc.parent_column_id = c.column_id AND dc.parent_object_id = c.object_id 
    WHERE 
     is_system_named = 1 

DECLARE @OldConstraintName sysname, @TableName sysname, @ColumnName sysname 

OPEN DFCursor 

FETCH NEXT FROM DFCursor INTO @OldConstraintName, @TableName, @ColumnName 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    DECLARE @Stmt NVARCHAR(999) 

    SET @Stmt = 'dbo.sp_rename @objName = ''' + @OldConstraintName + ''', @NewName = ''DF_' + @TableName + '_' + @ColumnName + ''', @objtype = ''OBJECT''' 

    PRINT @Stmt 
    EXEC (@Stmt) 

    FETCH NEXT FROM DFCursor INTO @OldConstraintName, @TableName, @ColumnName 
END 

CLOSE DFCursor 
DEALLOCATE DFCursor 
1

提供的解決方案將打破,如果DB已經在不同的模式類似的表。這是我對this solution的修改,我使用。

CREATE PROCEDURE dbo._ImplementNamingStandard 
@SELECT_Only  BIT = 1, 
@PrimaryKeys  BIT = 1, 
@ForeignKeys  BIT = 1, 
@Indexes   BIT = 1, 
@UniqueConstraints BIT = 1, 
@DefaultConstraints BIT = 1, 
@CheckConstraints BIT = 1 

AS 
BEGIN 
SET NOCOUNT ON; 

DECLARE @sql NVARCHAR(MAX), @cr CHAR(2); 
SELECT @sql = N'', @cr = CHAR(13) + CHAR(10); 


DECLARE @TableLimit TINYINT, @ColumnLimit TINYINT; 
SELECT @TableLimit = 24, @ColumnLimit = 24; 

主鍵:

IF @PrimaryKeys = 1 
BEGIN 
    SELECT @sql = @sql + @cr + @cr + N'/* ---- Primary Keys ---- */' + @cr; 
    SELECT @sql = @sql + @cr + N'EXEC sp_rename @objname = N''' 
     + SCHEMA_NAME(schema_id) + '.' 
     + REPLACE(name, '''', '''''') + ''', @newname = N''PK_' 
     + LEFT(REPLACE(OBJECT_NAME(parent_object_id), '''', ''), @TableLimit) + ''';' 
    FROM sys.key_constraints 
    WHERE type = 'PK' 
    AND is_ms_shipped = 0; 
END 

外鍵:

IF @ForeignKeys = 1 
BEGIN 
    SELECT @sql = @sql + @cr + @cr + N'/* ---- Foreign Keys ---- */' + @cr; 
    SELECT @sql = @sql + @cr + N'EXEC sp_rename @objname = N''' 
     + SCHEMA_NAME(f.schema_id) + '.' 
     + REPLACE(f.name, '''', '''''') + ''', @newname = N''FK_' 
     + LEFT(REPLACE(t.name, '''', ''), @TableLimit) 
     + '_' + LEFT(REPLACE(t2.name, '''', ''), @TableLimit)   
     + '_' + LEFT(REPLACE(c.name, '''', ''), @ColumnLimit) 
     + ''';' 
    FROM 
     sys.foreign_keys as f 
     inner join sys.foreign_key_columns as fk on f.object_id = fk.constraint_object_id 
     inner join sys.tables as t on fk.parent_object_id = t.object_id   
     inner join sys.tables as t2 on fk.referenced_object_id = t2.object_id 
     inner join sys.columns as c on fk.parent_object_id = c.object_id and 
             fk.parent_column_id = c.column_id 


    WHERE f.is_ms_shipped = 0; 
END 

唯一約束:

IF (@UniqueConstraints = 1 OR @Indexes = 1) 
     BEGIN 
      SELECT @sql = @sql + @cr + @cr + N'/* ---- Indexes/Unique Constraints ---- */' + @cr; 
      SELECT @sql = @sql + @cr + N'EXEC sp_rename @objname = N''' 
     + CASE is_unique_constraint WHEN 0 THEN 
     QUOTENAME(REPLACE(OBJECT_NAME(i.[object_id]), '''', '''''')) + '.' ELSE '' END 
       + QUOTENAME(REPLACE(i.name, '''', '''''')) + ''', @newname = N''' 
       + CASE is_unique_constraint WHEN 1 THEN 'UQ_' ELSE 'IX_' 
        + CASE is_unique WHEN 1 THEN 'U_' ELSE '' END 
       END + CASE has_filter WHEN 1 THEN 'F_' ELSE '' END 
       + LEFT(REPLACE(OBJECT_NAME(i.[object_id]), '''', ''), @TableLimit) 
       + '_' + STUFF((SELECT '_' + LEFT(REPLACE(c.name, '''', ''), @ColumnLimit) 
        FROM sys.columns AS c 
         INNER JOIN sys.index_columns AS ic 
         ON ic.column_id = c.column_id 
         AND ic.[object_id] = c.[object_id] 
        WHERE ic.[object_id] = i.[object_id] 
        AND ic.index_id = i.index_id 
        AND is_included_column = 0 
        ORDER BY ic.index_column_id FOR XML PATH(''), 
        TYPE).value('.', 'nvarchar(max)'), 1, 1, '') +''';' 
      FROM sys.indexes AS i 
      WHERE index_id > 0 AND is_primary_key = 0 AND type IN (1,2) 
      AND OBJECTPROPERTY(i.[object_id], 'IsMsShipped') = 0; 
     END 

默認約束:

IF @DefaultConstraints = 1 
BEGIN 
    SELECT @sql = @sql + @cr + @cr + N'/* ---- DefaultConstraints ---- */' + @cr; 
    SELECT @sql = @sql + @cr + N'EXEC sp_rename @objname = N''' 
     + SCHEMA_NAME(schema_id) + '.' 
     + REPLACE(dc.name, '''', '''''') + ''', @newname = N''DF_' 
     + LEFT(REPLACE(OBJECT_NAME(dc.parent_object_id), '''',''), @TableLimit) 
     + '_' + LEFT(REPLACE(c.name, '''', ''), @ColumnLimit) + ''';' 
    FROM sys.default_constraints AS dc 
    INNER JOIN sys.columns AS c 
    ON dc.parent_object_id = c.[object_id] 
    AND dc.parent_column_id = c.column_id 
    AND dc.is_ms_shipped = 0; 
END 

檢查約束:

IF @CheckConstraints = 1 
BEGIN 
    SELECT @sql = @sql + @cr + @cr + N'/* ---- CheckConstraints ---- */' + @cr; 
    SELECT @sql = @sql + @cr + N'EXEC sp_rename @objname = N''' 
     + SCHEMA_NAME(schema_id) + '.' 
     + REPLACE(cc.name, '''', '''''') + ''', @newname = N''CK_' 
     + LEFT(REPLACE(OBJECT_NAME(cc.parent_object_id), '''',''), @TableLimit) 
     + '_' + LEFT(REPLACE(c.name, '''', ''), @ColumnLimit) + ''';' 
    FROM sys.check_constraints AS cc 
    INNER JOIN sys.columns AS c 
    ON cc.parent_object_id = c.[object_id] 
    AND cc.parent_column_id = c.column_id 
    AND cc.is_ms_shipped = 0; 
END 


SELECT @sql; 


IF @SELECT_Only = 0 AND @sql > N'' 
BEGIN 
    EXEC sp_executesql @sql; 
END