2012-05-19 16 views
6

मैं तालिकाओं का एक बहुत कुछ के साथ एक डेटाबेस है, और मुझे प्राथमिक/विदेशी कुंजी, अनुक्रमित और निम्नलिखित नियमों के अनुसार डिफ़ॉल्ट की कमी नाम बदलना चाहते हैं:चाबियाँ, अनुक्रमित, बाधाओं के लिए एक नामकरण मानक लागू करने

  • प्राथमिक कुंजी: PK_<table name>
  • विदेश कुंजियाँ: FK_<table_name>_<column name1>_column name2>...
  • इंडेक्स: IX_<table_name>_<column name1>_column name2>...
  • डिफ़ॉल्ट प्रतिबंध: DF_<table_name>_<column name>
  • सी बिल्ली की बाधाएं: CK_<table_name>_<column name>

किसी ने पहले से ही एक समान SQL स्क्रिप्ट किया है?

+0

आप और अधिक नियमों को निर्दिष्ट कर सकते हैं, उदाहरण के लिए यदि आपकी अनुक्रमणिका फ़िल्टर की गई है या कॉलम शामिल है, तो क्या आप उन्हें भी निर्दिष्ट करना चाहते हैं, या केवल कुंजी कॉलम? चेक बाधाओं और अद्वितीय बाधाओं के बारे में क्या? –

+0

मेरे पास नहीं कह सकता है, लेकिन मैं सामान बनाने के लिए कभी भी GUI का उपयोग नहीं करता, और मैं हमेशा स्क्रिप्ट में अपना सामान नाम देता हूं। आप उपर्युक्त उपर्युक्त कर सकते हैं, लेकिन मुझे लगता है कि उपरोक्त को समझने के बजाय डीबी को स्क्रिप्ट करना और संपादित करना आसान होगा। –

+0

एक और विचार यह है कि उन वस्तुओं से निपटने का तरीका जो उनके नाम पर अंडरस्कोर हैं। उस मामले के लिए विदेशी कुंजी के ऑब्जेक्ट नाम को पढ़ने में काफी भ्रमित हो सकता है, जहां 'Document_Folder' का नाम' फ़ोल्डर 'नाम' कॉलर 'नामक' फ़ोल्डर 'नामक कॉलम द्वारा संदर्भित किया गया है। '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 

इंडेक्स के लिए, यह किसी का नाम बदल देगा I ndexes 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 संग्रहीत प्रक्रिया को अपने एफके बाधा का नाम बदलने के लिए जो कुछ भी आप चाहते हैं उसका नाम बदलने के लिए निष्पादित करें।

मूल रूप से एक एकल विशाल SQL कथन का निर्माण करने के लिए हारून के दृष्टिकोण का उपयोग करके, आप कर्सर का उपयोग किए बिना भी दूर हो सकते हैं।

यह आपके नामकरण सम्मेलन में "सिस्टम-नामित" डिफ़ॉल्ट बाधाओं का नाम बदलने के लिए बहुत ही समान कोड होगा - यह उपरोक्त के समान दृष्टिकोण का उपयोग करता है, SELECT सिस्टम कैटलॉग दृश्यों के विरुद्ध, और फिर कर्सर को फिर से चालू करने के लिए सभी प्रविष्टियों और निर्माण और उसे निष्पादित एसक्यूएल नाम बदलने बयान: अगर डीबी अलग स्कीमा में समान टेबल है

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

परंतु समाधान टूट जाएगा। यहां 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 
संबंधित मुद्दे