2016-07-01 11 views
0

基本テーブルとそのア​​ーカイブテーブル(通常はarc_ +ベーステーブル名)を比較するには、次のように書いて両方のテーブルの列数を表示します。一方の側ではなく、他に存在する列、および両側の間で異なっているカラム:2つの "brother" SQLテーブルの構造を比較

DECLARE @base_tbl varchar(20) = 'appointments' 

DECLARE @arch_tbl varchar(20) = 'arc_' + @base_tbl 
DECLARE @schema varchar(35) = 'some' 

-- Count in base table. 
SELECT @base_tbl, COUNT(*) 
FROM information_schema.columns 
WHERE TABLE_NAME = @base_tbl AND TABLE_SCHEMA = @schema 

-- Count in archive table. 
SELECT @arch_tbl, COUNT(*) 
FROM information_schema.columns 
WHERE TABLE_NAME = @arch_tbl AND TABLE_SCHEMA = @schema 

-- Columns only in the base or in the archive table. 
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, IS_NULLABLE 
FROM information_schema.columns 
WHERE TABLE_NAME IN (@base_tbl, @arch_tbl) AND TABLE_SCHEMA = @schema 
    AND COLUMN_NAME IN (
     SELECT DISTINCT COLUMN_NAME FROM 
     (
      SELECT TABLE_NAME, COLUMN_NAME 
      FROM information_schema.columns 
      WHERE TABLE_NAME = @base_tbl AND TABLE_SCHEMA = @schema 
       UNION 
      SELECT TABLE_NAME, COLUMN_NAME 
      FROM information_schema.columns 
      WHERE TABLE_NAME = @arch_tbl AND TABLE_SCHEMA = @schema 
    ) u 
     GROUP BY COLUMN_NAME 
     HAVING COUNT(*) = 1) 
ORDER BY COLUMN_NAME, TABLE_NAME 

-- Differences. 
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, IS_NULLABLE 
FROM information_schema.columns 
WHERE TABLE_NAME IN (@base_tbl, @arch_tbl) AND TABLE_SCHEMA = @schema 
    AND COLUMN_NAME IN (
     SELECT DISTINCT COLUMN_NAME FROM 
     (
      SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION 
      FROM information_schema.columns 
      WHERE TABLE_NAME = @base_tbl AND TABLE_SCHEMA = @schema 
       UNION 
      SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION 
      FROM information_schema.columns 
      WHERE TABLE_NAME = @arch_tbl AND TABLE_SCHEMA = @schema 
    ) v 
GROUP BY COLUMN_NAME 
HAVING COUNT(*) > 1) 
ORDER BY COLUMN_NAME, TABLE_NAME 

私は読みやすさや、より良い出力をサポートするために、これは改善できるかどうかを疑問に思っています。 WDYT?

+2

これはhttp://codereview.stackexchange.com/ –

+0

はそれについて知らなかったために、より良い可能性があります。確かにそれを使用します! Thx – user3341592

答えて

1

FULL JOINはこれをすべて行いますか?

SELECT c1.COLUMN_NAME, c1.DATA_TYPE, c2.COLUMN_NAME, c2.DATA_TYPE 
FROM 
(
    SELECT * 
    FROM information_schema.columns c1 
    WHERE c1.TABLE_NAME = 'xxx' AND c1.table_schema = 'xxx' 
) c1 
FULL JOIN 
(
    SELECT * 
    FROM information_schema.columns c2 
    WHERE c2.TABLE_NAME = 'yyy' AND c2.table_schema = 'yyy' 
) c2 
ON c1.COLUMN_NAME = c2.COLUMN_NAME 
ORDER BY 
    CASE WHEN c1.COLUMN_NAME IS NULL OR c2.COLUMN_NAME IS NULL THEN 0 ELSE 1 END, 
    ISNULL(c1.COLUMN_NAME, c2.COLUMN_NAME) 
+0

よく知られているいくつかのテーブルを繰り返す(私のアプリでは、 "t1"、 "t2"、 "t3"と言う)、どうしたらよいですか?上記をストアドプロシージャとしてカプセル化しますか?または、forループを作成する方法はありますか? – user3341592

+0

ところで、非常にスマートな出力です。異なる基準(型違いや長さ違いなど)に基づいて列を簡単に選択することができます。私が持っていたものよりもはるかに良い!どうもありがとう。 – user3341592

+0

_ "よく知られたテーブルのカップル" _ - 一度に2つ以上のテーブルを比較したい、またはテーブルのペアを順次比較したいですか? –

関連する問題