【问题标题】:Compare the structure of two "brother" SQL tables比较两个“兄弟”SQL表的结构
【发布时间】:2016-11-04 01:53:09
【问题描述】:

为了比较基表和它的存档表(通常是arc_ + 基表名称),我编写了以下内容来显示两个表中的列数,即存在于一侧但不存在的列另一方面,以及两边不同的列:

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?

【问题讨论】:

标签: sql sql-server comparison schema


【解决方案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)

【讨论】:

  • 要迭代几个著名的表(在我的应用程序中——比如说“t1”、“t2”和“t3”),我应该怎么做?将上述内容封装为存储过程?或者有没有办法制作一个“for”循环?
  • 顺便说一句,非常智能的输出,可以轻松地根据不同的标准(具有类型差异或长度差异等的那些)选择列。比我拥有的好多了!非常感谢。
  • “几个著名的表” - 您想同时比较两个以上的表,还是要按顺序比较多个表?
  • 最新的(将 t1 与 arc_t1 进行比较,然后将 t2 与 arc_t2 进行比较,依此类推,都在一个“报告”中)。
  • 声明@table,将成对的表名放在此处进行比较,并在while循环中连续读取。声明@report表,将每次迭代结果(全连接的输出)放入其中。
猜你喜欢
  • 2014-02-05
  • 1970-01-01
  • 1970-01-01
  • 2018-02-25
  • 1970-01-01
  • 2013-02-18
  • 2019-09-08
  • 2012-08-01
  • 1970-01-01
相关资源
最近更新 更多