【问题标题】:Changing columns collation using batch sql in sql server 2005在 sql server 2005 中使用批处理 sql 更改列排序规则
【发布时间】:2011-06-29 16:30:27
【问题描述】:

我接管了一个数据库。似乎在某些时候默认数据库排序规则已更改。结果,某些列具有旧的默认排序规则,但是在更改排序规则后添加的新列具有新的排序规则。还有大量使用联合的存储过程代码。当该代码执行时,我得到了

Cannot resolve collation conflict for column 5 in SELECT statement.

错误(例如,第一个 SELECT 返回排序规则 A 中的列,而第二个 SELECT 返回排序规则 B 中的列)。有没有办法编写一个 SQL,例如选择所有具有排序规则 SQL_Latin1_General_CP1_CI_AS (旧排序规则)到新排序规则 Latin1_General_CI_AS 的列?

谢谢

【问题讨论】:

    标签: sql-server sql-server-2005 tsql collation


    【解决方案1】:

    这样的事情应该可以解决问题

    • 查找排序规则不正确的所有列
    • 为每个不正确的列编写一个更改表语句和更改列语句

      DECLARE @sql nvarchar(4000) 
            , @tablename sysname
            , @name sysname
            , @datatype sysname
            , @length int
            , @precision int
            , @scale int
            , @is_nullable bit
      
      DECLARE cur_collations CURSOR LOCAL READ_ONLY
      FOR SELECT tablename = object_name(object_id)
               , name
               , TYPE_NAME(user_type_id)
               , max_length
            FROM sys.columns 
           WHERE collation_name = 'SQL_Latin1_General_CP1_CI_AS'
      
      OPEN cur_collations
      
      FETCH NEXT FROM cur_collations INTO @tablename, @name, @datatype, @length
      
      WHILE (@@fetch_status <> -1)
        BEGIN
          IF (@@fetch_status <> -2)
            BEGIN
                set @sql = N'
                  ALTER TABLE ' + QUOTENAME(@tablename) + N'
                  ALTER COLUMN ' + QUOTENAME(@name) + N' ' + QUOTENAME(@datatype) + N'(' + cast(@length as nvarchar(10)) + N') 
                  COLLATE Latin1_General_CI_AS
                  ' + case when @is_nullable = 1 then N'NULL' else N'NOT NULL' end + N' '
                EXEC (@sql)
            END
          FETCH NEXT FROM cur_collations INTO @tablename, @name, @datatype, @length
        END
      
      CLOSE cur_collations
      DEALLOCATE cur_collations
      

    【讨论】:

    • 看起来棒极了 :) 我很快就会试一试。谢谢
    【解决方案2】:

    更新

    • 支持架构
    • 正确实现 is_nullable
    
    DECLARE
        @sql nvarchar(4000),
        @tablename sysname,
        @schemaname sysname,
        @name sysname,
        @datatype sysname,
        @length int,
        @precision int,
        @scale int,
        @is_nullable bit
    
    DECLARE cur_collations CURSOR LOCAL READ_ONLY FOR
    SELECT
        tablename = OBJECT_NAME(columns.object_id),
        schemaname = SCHEMA_NAME(schema_id),
        columns.name,
        TYPE_NAME(user_type_id),
        max_length,
        is_nullable
    FROM sys.columns
        INNER JOIN sys.objects on columns.object_id = objects.object_id
    WHERE
        collation_name = 'SQL_Latin1_General_CP1_CI_AS'
    
    OPEN cur_collations
    
    FETCH NEXT FROM cur_collations INTO @tablename, @schemaname, @name, @datatype, @length, @is_nullable
    
    WHILE (@@fetch_status  -1) BEGIN
        IF (@@fetch_status  -2) BEGIN
            SET @sql = N'ALTER TABLE ' + QUOTENAME(@schemaname) + '.' + QUOTENAME(@tablename) + N' ALTER COLUMN ' + QUOTENAME(@name) + N' ' + QUOTENAME(@datatype) + N'(' + cast(@length as nvarchar(10)) + N') COLLATE Latin1_General_CI_AS ' + case when @is_nullable = 1 then N'NULL' else N'NOT NULL' end + N' '
            --EXEC (@sql)
            PRINT @sql
        END
        FETCH NEXT FROM cur_collations INTO @tablename, @schemaname, @name, @datatype, @length, @is_nullable
    END

    【讨论】:

      猜你喜欢
      • 2011-03-28
      • 2010-10-25
      • 2012-02-22
      • 1970-01-01
      • 2016-11-17
      • 2010-10-09
      • 2015-04-03
      • 2010-09-05
      • 2011-07-19
      相关资源
      最近更新 更多