确定列排序规则不匹配的位置

时间:2014-03-13 19:54:40

标签: sql sql-server tsql

当我尝试通过UNION ALL语句连接两个相当大的表时,我收到以下排序规则冲突错误。

SELECT * FROM [TABLEA] 
UNION ALL
SELECT * FROM [TABLEB]

Msg 457, Level 16, State 1, Line 1
Implicit conversion of varchar value to varchar cannot be performed because the collation of the value is unresolved due to a collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "SQL_Latin1_General_CP1_CS_AS" in UNION ALL operator.

我想确定哪些列完全不匹配,但不熟悉查询sys.columns或information_schema。

4 个答案:

答案 0 :(得分:3)

这应该做(假设两个表上的列具有相同的名称):

SELECT *
FROM (  SELECT *
        FROM sys.columns
        WHERE OBJECT_NAME(object_id) = 'TABLEA') A
INNER JOIN (SELECT *
            FROM sys.columns
            WHERE OBJECT_NAME(object_id) = 'TABLEB') B
    ON A.name = B.name
WHERE A.collation_name <> B.collation_name

答案 1 :(得分:1)

只需将MyTable1MyTable2替换为您的表名

即可
SELECT OBJECT_NAME(c.object_id) as TableName
       ,c.name AS ColumnName
       ,c.collation_name as CollationName
    FROM sys.columns AS c
    JOIN sys.tables AS t
        ON c.object_id = t.object_id
    WHERE t.name IN ( 'MyTableA', 'MyTableB' )
    AND c.collation_name IS NOT NULL

如果列名与您完全相同

WITH    TableA
          AS (
               SELECT OBJECT_NAME(c.object_id) AS TableName
                   ,c.name AS ColumnName
                   ,c.collation_name AS CollationName
                FROM sys.columns AS c
                JOIN sys.tables AS t
                    ON c.object_id = t.object_id
                WHERE t.name IN ( 'TableA' )
                    AND c.collation_name IS NOT NULL
             ),
        TableB
          AS (
               SELECT OBJECT_NAME(c.object_id) AS TableName
                   ,c.name AS ColumnName
                   ,c.collation_name AS CollationName
                FROM sys.columns AS c
                JOIN sys.tables AS t
                    ON c.object_id = t.object_id
                WHERE t.name IN ( 'TableB' )
                    AND c.collation_name IS NOT NULL
             )
    SELECT a.TableName
           ,a.ColumnName
           ,a.CollationName
           ,b.TableName
           ,b.ColumnName
           ,b.CollationName
        FROM tableA AS a
        JOIN TableB AS b
            ON a.ColumnName = b.ColumnName
               AND a.CollationName <> b.CollationName

答案 2 :(得分:1)

确定所有人都使用sys.columns ...我将使用information_schema以防万一他在SQL 2000上;)

如果列名相同(并且顺序相同):

SELECT *
FROM (SELECT TABLE_NAME, COLUMN_NAME, COLLATION_NAME
      FROM INFORMATION_SCHEMA.COLUMNS
      WHERE TABLE_NAME='TABLEA') A,
     (SELECT TABLE_NAME, COLUMN_NAME, COLLATION_NAME
      FROM INFORMATION_SCHEMA.COLUMNS
      WHERE TABLE_NAME='TABLEB') B
WHERE A.COLUMN_NAME = B.COLUMN_NAME
AND ISNULL(A.COLLATION_NAME,'') <> ISNULL(B.COLLATION_NAME,'')

或者,按列顺序(序数)进行比较:

SELECT *
FROM (SELECT TABLE_NAME, COLUMN_NAME, COLLATION_NAME, ORDINAL_POSITION
      FROM INFORMATION_SCHEMA.COLUMNS
      WHERE TABLE_NAME='TableA') A
FULL OUTER JOIN (SELECT TABLE_NAME, COLUMN_NAME, COLLATION_NAME, ORDINAL_POSITION
      FROM INFORMATION_SCHEMA.COLUMNS
      WHERE TABLE_NAME='TableB') B
   ON A.ORDINAL_POSITION = B.ORDINAL_POSITION
WHERE ISNULL(A.COLLATION_NAME,'') <> ISNULL(B.COLLATION_NAME,'')

答案 3 :(得分:0)

这应该让你从那个方向开始。

 WITH CTE as 
(   SELECT tbl.NAME AS Table_name
        , col.NAME AS [Column_name]
        , col.collation_name
        , col.column_id
    FROM sys.columns col
    INNER JOIN sys.tables tbl
        ON col.object_id = tbl.object_id  
    WHERE Col.collation_name in ('SQL_Latin1_General_CP1_CI_AS'
    ,'SQL_Latin1_General_CP1_CS_AS')    
 )
 SELECT * FROM CTE A
 inner join CTE b
 on A.column_id=B.column_id
 WHERE A.Table_name='PSS601'
 and B.Table_name='PSS604'
 and A.collation_name <> B.collation_name

然后要更改排序规则,请使用COLLATE关键字。

Column_name COLLATE Collation_name