生成脚本以自动重命名默认约束

jco*_*and 8 sql-server dynamic-sql sql-server-2008-r2

背景:我们的一些默认列约束是在没有明确名称的情况下生成的,因此我们得到了因服务器而异的有趣名称,例如: DF__User__TimeZoneIn__5C4D869D

我希望它们都可以使用一致的命名进行管理,DF_Users_TimeZoneInfo这样我们就可以确保未来的目标表存在适当的约束(比如在 RedGate 比较中,甚至只是在视觉上)

我有一个主要适用于我想要的脚本:

select 'sp_rename N''[' + s.name + '].[' + d.name + ']'', 
   N''[DF_' + t.name + '_' + c.name + ']'', ''OBJECT'';'
from sys.tables t
    join
    sys.default_constraints d
        on d.parent_object_id = t.object_id
    join
    sys.columns c
        on c.object_id = t.object_id
        and c.column_id = d.parent_column_id
    join sys.schemas s
        on t.schema_id = s.schema_id
WHERE d.NAME like 'DF[_][_]%'
Run Code Online (Sandbox Code Playgroud)

但这只是给了我一个结果集,而不是我实际上可以传递给 exec 或其他任何东西的东西。

我怎样才能做到这一点,以便我可以只执行这些sp_rename脚本,而不必求助于复制所有返回的元素并将它们粘贴到新的查询窗口中并再次运行它们?尝试尽可能多地保存击键,以便我可以在许多环境中纠正此问题。

在此处输入图片说明

Aar*_*and 16

好的,有几件事。

  1. EXEC执行存储过程时总是使用;简写 withoutEXEC仅在它是批处理中的第一条语句时才有效(这里不是这种情况)。
  2. 总是使用分号终止符——在这种情况下,它们可以用来代替漂亮的回车和缩进,但它们总是明智的。
  3. 始终使用QUOTENAME()而不是自己手动应用方括号。在这种情况下,您可能是安全的,但在某些情况下,手动方法会中断。
  4. 您可以测试PRINT输出,但如果您的总命令数 > 8k,则它不一定是完整的(请参阅此提示以了解一些替代方法)。

    DECLARE @sql nvarchar(max) = N'';
    
    SELECT @sql += N'EXEC sys.sp_rename N''' 
        + QUOTENAME(s.name) + '.' + QUOTENAME(d.name) 
        + ''', N''DF_' + t.name + '_' + c.name + ''', ''OBJECT'';'
      FROM sys.tables AS t
      INNER JOIN sys.default_constraints AS d
         ON d.parent_object_id = t.object_id
      INNER JOIN sys.columns AS c
         ON c.object_id = t.object_id
        AND c.column_id = d.parent_column_id
      INNER JOIN sys.schemas AS s
         ON t.schema_id = s.schema_id
      WHERE d.NAME LIKE N'DF[_][_]%';
    
    PRINT @sql;
    -- EXEC sys.sp_executesql @sql;
    
    Run Code Online (Sandbox Code Playgroud)

  • 是的,尝试执行此操作:`sp_help; sp_help;`. (3认同)