【问题标题】:How to Change All Sql Columns of One DataType into Another如何将一种数据类型的所有 Sql 列更改为另一种数据类型
【发布时间】:2010-11-22 14:08:23
【问题描述】:

我有一个数据库 (Sql Server 2005),其中有几十个 tables,每个数据库都有多个 columns(平均 10-20 个),数据类型设置为 nvarchar(max)。这绝对是在扼杀性能(其中一些列被用于joins,一些表有 100K+ 行)。我想将所有这些列更改为varchar(250)。自动化的最佳方法是什么? (我可以使用Management Studio,或者我可以创建一个实用程序来通过可以访问数据库的ASP.net 网站来执行此操作,以更容易者为准)。

【问题讨论】:

    标签: sql sql-server sql-server-2005 performance types


    【解决方案1】:

    这是一个使用INFORMATION_SCHEMA.COLUMNS 查找所有*varchar(max) 列并将它们转换为varchar(255) 的工作脚本:

    declare @schema nvarchar(255)
    declare @table nvarchar(255)
    declare @col nvarchar(255)
    declare @dtype nvarchar(255)
    declare @sql nvarchar(max)
    
    declare maxcols cursor for
    select
        c.TABLE_SCHEMA,
        c.TABLE_NAME,
        c.COLUMN_NAME,
        c.DATA_TYPE
    from
    INFORMATION_SCHEMA.COLUMNS c
    inner join INFORMATION_SCHEMA.TABLES t on
        c.TABLE_CATALOG = t.TABLE_CATALOG
        and c.TABLE_SCHEMA = t.TABLE_SCHEMA
        and c.TABLE_NAME = t.TABLE_NAME
        and t.TABLE_TYPE = 'BASE TABLE'
    where
        c.DATA_TYPE like '%varchar'
        and c.CHARACTER_MAXIMUM_LENGTH = -1
    
    open maxcols
    
    fetch next from maxcols into @schema, @table, @col, @dtype
    
    while @@FETCH_STATUS = 0
    begin
        set @sql = 'alter table [' + @schema + '].[' + @table + 
            '] alter column [' + @col + '] ' + @dtype + '(255)'
        exec sp_executesql @sql
    
        fetch next from maxcols into @schema, @table, @col, @dtype
    end
    
    close maxcols
    deallocate maxcols
    

    这是我唯一允许使用的游标,但这是一个很好的选择。本质上,它会找到所有*varchar(max),构建alter 语句,然后使用sp_executesql 执行它。

    享受吧!

    【讨论】:

    • 这并不完美,因为它还会从视图中引入列
    • 现在,如何在执行此操作时删除约束并将它们放回原处,因为我们无法在有约束的情况下更改 cols?
    • 如何包含一个检查以仅适用于最大长度
    【解决方案2】:

    您可以使用以下方法轻松找到它们:

    select 'alter table ' + quotename(o.name) + ' alter column ' + quotename(c.name) + ' varchar(250); '
    from sys.columns c
      join
      sys.objects o
      on o.object_id = c.object_id
    where o.type = 'U'
    and c.user_type_id = 231
    and c.max_length = -1
    

    所以现在只需获取查询结果并运行它。

    罗伯

    【讨论】:

    • 可能还值得一提...如果您声明@qry nvarchar(max),然后选择@qry = (.... for xml path(''));执行 sp_executesql @qry; --您可以一步完成。 .... 是我当前的查询。但是你不能很好地“检查”它。
    • 是否需要考虑列的可空性?这会将列更改为可为空,因为它没有指定任何一种方式吗?
    【解决方案3】:

    我认为完成此任务的最佳方法是为当前数据库生成脚本,然后在文本文件中将 nvarchar(max) 替换为 varchar(250),然后创建新数据库。 之后使用导入/导出实用程序将数据传输到新数据库。

    【讨论】:

    • 这不起作用 - SSIS 将返回一条错误消息,指出源表和目标表之间的列元数据不匹配
    猜你喜欢
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    • 2020-05-27
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多