Rename all system name restrictions programmatically

I have a distributed application that lives on many customer sites. The previous developer didn't give user-specified constraints very well. How can I rename all constraints to something like "DF_ [TableName] _ [ColumnName]"? I could hover over the list of tables. Do you think it will be a problem if I post it to a client's site? Or is there a better way to do this?

SELECT sys.schemas.name as [Schema],
sys.tables.name as [TableName],
sys.all_columns.name as [Column],
  default_constraints.name as [Constraint]
  FROM
    sys.all_columns
       INNER JOIN sys.tables
        ON all_columns.object_id = tables.object_id
       INNER JOIN sys.schemas
        ON tables.schema_id = schemas.schema_id
       INNER JOIN sys.default_constraints
        ON all_columns.default_object_id = default_constraints.object_id
       where default_constraints.name like '%[0-9]%'

      

+3


source to share


1 answer


If you use a naming convention for each type of constraint, this will help you. Here I am posting an example of how to handle this default constraint. The procedure will find the default constraints, discard those that do not match the naming conventions, and create new ones with the old definition.

This is a simple one-time run version

 DECLARE @SchemaName sysname = 'dbo';
 DECLARE @TableName sysname = NULL;
 DECLARE @ColumnName sysname = NULL;
 DECLARE @sql VARCHAR(max) = '';

SELECT
@sql += 
  'ALTER TABLE [' + s.name + '].[' + o.name + '] DROP CONSTRAINT [' + dc.name + ']; ' + 
  'ALTER TABLE [' + s.name + '].[' + o.name + '] ADD  CONSTRAINT [DF_' + o.name + '_' + c.name + '] DEFAULT ' + dc.DEFINITION + ' FOR [' + c.name + '];'

  FROM dbo.sysobjects do
        INNER JOIN dbo.sysobjects o ON do.parent_obj = o.id
        INNER JOIN sys.default_constraints dc ON dc.object_id = do.id
        INNER JOIN sys.columns c ON c.object_id = o.id
                   AND c.column_id = dc.parent_column_id
        INNER JOIN sys.schemas s ON s.schema_id = dc.schema_id
  WHERE o.type = 'U' 
       AND do.type = 'D'
       AND s.name = @SchemaName
       AND o.name = CASE WHEN ISNULL(@TableName,'') = '' 
                        THEN o.name 
                        ELSE @TableName END
       AND c.name = CASE WHEN ISNULL(@ColumnName,'') = ''
                         THEN c.name 
                         ELSE @ColumnName END
       AND do.name NOT LIKE 'DF_' + o.name + '_' + c.name
  ORDER BY o.name
 --PRINT (@sql)
  EXECUTE(@sql)

      



And this is the procedure in case you want to continue the procedure every time after a while.

USE [YourDatabaseName]
    GO
    -- Check if the procedure exists and drop it if so
    IF  EXISTS (SELECT * 
                FROM sys.objects 
                WHERE object_id = OBJECT_ID(N'[dbo].[usp_NamingConventionDefaultConstraint]') AND type in (N'P', N'PC'))
    DROP PROCEDURE [dbo].[usp_NamingConventionDefaultConstraint]
    GO

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    --procedure can be used for specific schema/table/columns or those can be left null to include everything. 
    CREATE PROC [dbo].[usp_NamingConventionDefaultConstraint]
                @SchemaName sysname = 'dbo',
                @TableName sysname = NULL,
                @ColumnName sysname = NULL
    AS
    BEGIN
        SET NOCOUNT ON;

        DECLARE @sql VARCHAR(max)

        DECLARE GetIndexes CURSOR
        FOR
            SELECT
 --here drop the old constraint and create a new one with the old definition
            'ALTER TABLE [' + s.name + '].[' + o.name + '] DROP CONSTRAINT [' + dc.name + ']; ' + 
            'ALTER TABLE [' + s.name + '].[' + o.name + '] ADD  CONSTRAINT [DF_' + o.name + '_' + c.name + '] DEFAULT ' + dc.DEFINITION + ' FOR [' + c.name + '];'
            AS dc_alter
            FROM dbo.sysobjects do
            INNER JOIN dbo.sysobjects o ON do.parent_obj = o.id
            INNER JOIN sys.default_constraints dc ON dc.object_id = do.id
            INNER JOIN sys.columns c ON c.object_id = o.id 
                                     AND c.column_id = dc.parent_column_id
            INNER JOIN sys.schemas s ON s.schema_id = dc.schema_id
            WHERE o.type = 'U' 
            -- work only on default constraints 
            AND do.type = 'D'
            AND s.name = @SchemaName
            AND o.name = CASE WHEN ISNULL(@TableName,'') = '' THEN o.name ELSE @TableName END
            AND c.name = CASE WHEN ISNULL(@ColumnName,'') = '' THEN c.name ELSE @ColumnName END
            -- here goes the naming convention you have in mind
            --DF_TableName_ColumnName
            AND do.name NOT LIKE 'DF_' + o.name + '_' + c.name
            ORDER BY o.name

        OPEN GetIndexes

        FETCH NEXT FROM GetIndexes
        INTO @sql   

        WHILE @@FETCH_STATUS = 0
        BEGIN
            IF  ISNULL(@sql,'')<>''
            BEGIN
                EXEC (@sql)
            END

            FETCH NEXT FROM GetIndexes
            INTO @sql   
        END

        CLOSE   GetIndexes
        DEALLOCATE  GetIndexes

    END
    GO

      

+3


source







All Articles