我使用
在我的数据库中重命名了一个表EXEC sp_rename 'tblOldAndBusted', 'tblNewAndShiny'
并且所有外键约束都更新为新表名,但它们仍然基于旧表名命名。例如,我现在有 FK_tblOldAndBusted_tblTastyData ,但我想要 FK_tblNewAndShiny_tblTastyData 。
有一种简单的方法来编写脚本吗?
另外,我是不是太肛门了?我知道数据库在约束中使用旧表名称可以正常工作,但感觉就像broken windows。
答案 0 :(得分:22)
尝试:
exec sp_rename 'FK_tblOldAndBusted_tblTastyData', 'FK_tblNewAndShiny_tblTastyData', 'object'
此外,在处理非默认schema
时,存在关于重命名此类内容的错误。
答案 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'
答案 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)
如果要重命名的对象是约束,则object_name的格式必须为schema.constraint。
所以正确的形式是:
exec sp_rename 'schema.oldname','newname', 'object'
在架构上加上旧名称。
不要在新名称前添加模式...