如何重命名约束

时间:2010-09-16 17:37:16

标签: sql-server

我使用

在我的数据库中重命名了一个表
EXEC sp_rename 'tblOldAndBusted', 'tblNewAndShiny'

并且所有外键约束都更新为新表名,但它们仍然基于旧表名命名。例如,我现在有 FK_tblOldAndBusted_tblTastyData ,但我想要 FK_tblNewAndShiny_tblTastyData

有一种简单的方法来编写脚本吗?

另外,我是不是太肛门了?我知道数据库在约束中使用旧表名称可以正常工作,但感觉就像broken windows

8 个答案:

答案 0 :(得分:22)

尝试:

exec sp_rename 'FK_tblOldAndBusted_tblTastyData', 'FK_tblNewAndShiny_tblTastyData', 'object'

此外,在处理非默认schema时,存在关于重命名此类内容的错误。

Cannot rename a default constraint for a table in a schema which is not dbo by rsocol @Microsoft Connect

答案 1 :(得分:4)

我不是游标的忠实粉丝,这可以写得更简单。

DECLARE @SQLCmd varchar(MAX) = ''
SELECT 
    @SQLCmd += 'EXEC sp_rename ''' + dc.name + ''', ''DF' + 
                OBJECT_NAME( dc.parent_object_id ) + c.name + ''', ''OBJECT'';'
FROM 
    sys.default_constraints dc
    JOIN sys.columns c 
        ON c.object_id = dc.parent_object_id 
        AND c.column_id = dc.parent_column_id
WHERE 
    dc.name != 'DF' + object_name( dc.parent_object_id ) + c.name 
    AND OBJECT_NAME( dc.parent_object_id ) != 'dtproperties'
EXEC( @SqlCmd ) 

答案 2 :(得分:2)

如果有人感兴趣,我只需将名为“EnteredDate”的审计字段的所有默认约束重命名为特定模式。根据需要更新和替换。我希望这有助于并可能成为一个起点。

DECLARE @TableName VARCHAR(255), @ConstraintName VARCHAR(255)
DECLARE constraint_cursor CURSOR
    FOR 
        select b.name, c.name from 
        sys.all_columns a 
        inner join
        sys.tables b 
        on 
        a.object_id = b.object_id
        inner join
        sys.default_constraints c
        on a.default_object_id = c.object_id
        where 
            b.name <> 'sysdiagrams'
            and a.name = 'EnteredDate' -- column name
            and b.type = 'U'

OPEN constraint_cursor
FETCH NEXT FROM constraint_cursor INTO @TableName, @ConstraintName

WHILE @@FETCH_STATUS = 0
    BEGIN
        DECLARE @SqlScript VARCHAR(255) = ''
        SET @SqlScript = 'sp_rename ' + @ConstraintName + ', ''DF_' + @TableName + '_EnteredDate'', ''object'''
        EXEC(@SqlScript)
        SELECT @TableName, @ConstraintName, 'DF_' + @TableName + '_EnteredDate', @SqlScript 
        FETCH NEXT FROM constraint_cursor INTO @TableName, @ConstraintName
    END 
CLOSE constraint_cursor;
DEALLOCATE constraint_cursor;

答案 3 :(得分:2)

经过多次挖掘后,我发现它实际上必须采用这种形式:

EXEC sp_rename N'schema.MyIOldConstraint', N'MyNewConstraint', N'OBJECT'

Source

答案 4 :(得分:0)

如果要重命名太多,如何导出到转储,在所选的任何文本编辑器中编辑转储以替换表名,然后从dump恢复?我的意思是只输出约束的转储,而不是全部。

答案 5 :(得分:0)

基于user906573的脚本。生成脚本以重命名数据库中的所有默认值。用于纠正在创建时未明确命名的约束。

 --
-- Generates a script to rename defaults to the pattern DF_tablename_columnname
--

DECLARE @TableName VARCHAR(255), @ConstraintName VARCHAR(255), @ColumnName varchar(255), @SchemaName varchar(255)
DECLARE constraint_cursor CURSOR
    FOR 
        select b.name, c.name, a.name, sc.name
        from sys.all_columns a 
        inner join sys.tables b on a.object_id = b.object_id
        join sys.schemas sc on b.schema_id = sc.schema_id
        inner join sys.default_constraints c on a.default_object_id = c.object_id
        where 
            b.name <> 'sysdiagrams'
            and b.type = 'U'

OPEN constraint_cursor
FETCH NEXT FROM constraint_cursor INTO @TableName, @ConstraintName, @ColumnName, @SchemaName

WHILE @@FETCH_STATUS = 0
    BEGIN
        DECLARE @SqlScript VARCHAR(255) = ''
        SET @SqlScript = 'sp_rename ''' + @SchemaName + '.' + @ConstraintName + ''', ''' + @SchemaName + '.DF_' + @TableName + '_' + @ColumnName + ''', ''object''' + char(13) + char(10) + 'GO' + char(13) + char(10)
        --EXEC(@SqlScript)
        print @sqlscript
        FETCH NEXT FROM constraint_cursor INTO @TableName, @ConstraintName, @ColumnName, @SchemaName
    END 
CLOSE constraint_cursor;
DEALLOCATE constraint_cursor;

答案 6 :(得分:0)

我知道这个帖子有点陈旧但是我想在@ foxfire的答案后发布我的替代品,因为我对它进行了一些修改。当我遇到数据库时,它需要一小部分名称,因为有很多重命名,它使@sql截断。我还添加了错误处理以及用于处理除dbo之外的不同模式的模式名称。我选择不使用开始尝试,因此它可以在多个sql server版本中使用。可以操纵where子句以实现OP的原始意图。

BEGIN TRAN

DECLARE @sql varchar(MAX) = '...'

WHILE LEN(@sql) > 0 BEGIN
       SET @sql = '';

       SELECT TOP 50 @sql = @sql 
              + 'EXEC sp_rename N''' + SCHEMA_NAME(dc.[schema_id]) + '.' + dc.name 
              + ''', N''DF_' + OBJECT_NAME(dc.parent_object_id) + '_' + c.name 
              + ''', ''OBJECT'';' + CHAR(10)
       FROM sys.default_constraints dc
       inner join sys.columns c 
              ON c.object_id = dc.parent_object_id AND c.column_id = dc.parent_column_id
       WHERE dc.name LIKE 'DF[_][_]%' -- rename any auto named defaults

       PRINT @sql
       EXEC(@sql)

       IF @@ERROR <> 0 BEGIN 
              IF @@TRANCOUNT > 0 ROLLBACK TRAN
              BREAK;
       END
END

IF @@TRANCOUNT > 0 COMMIT TRAN
--IF @@TRANCOUNT > 0 ROLLBACK TRAN

答案 7 :(得分:0)

https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-rename-transact-sql?view=sql-server-ver15

如果要重命名的对象是约束,则object_name的格式必须为schema.constraint。

所以正确的形式是:

exec sp_rename 'schema.oldname','newname', 'object'

在架构上加上旧名称。

不要在新名称前添加模式...