2014-03-13 19 views
0

當我嘗試通過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。

+0

如果突出顯示SSMS並按表ALT-F1,它會顯示錶格模式,包括排序。快速簡單 - 您可以對兩個表格執行此操作,將它們並排放入Excel中,然後添加<>公式以比較整理值。 – JiggsJedi

回答

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 
+0

假設很多。 – 2014-03-13 20:09:42

+1

+1有一個假設upvote – Kermit

+0

是我的列名匹配,是的,我使用的是2008 R2。這很簡單,正是我所期待的。謝謝! –

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 
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 
1

確定每個人都在使用sys.columns ...我會以防萬一他是在SQL 2000使用information_schema

如果列名是相同的(在相同的順序):

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,'')