information_schema视图每列返回多行

时间:2013-08-30 16:08:44

标签: sql

我正在尝试编写一个查询,它将为我提供有关给定数据库列的某些关键信息,但到目前为止,我的查询似乎返回了一些奇怪的结果!我需要了解有关色谱柱尺寸,可空性,独特性等的信息。

那么为什么每列会得到多个结果?

SELECT
C.COLUMN_NAME AS COLUMN_NAME,
C.TABLE_NAME AS TABLE_NAME,
C.CHARACTER_MAXIMUM_LENGTH AS CHARACTER_MAXIMUM_LENGTH,
C.COLUMN_DEFAULT AS COLUMN_DEFAULT,
C.DATA_TYPE AS DATA_TYPE,
C.IS_NULLABLE AS IS_NULLABLE,
CASE WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
AND CONSTRAINT_NAME = CC.CONSTRAINT_NAME) THEN 1 ELSE 0 END AS IS_PRIMARY_KEY,
CASE WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'UNIQUE'
AND CONSTRAINT_NAME = CC.CONSTRAINT_NAME) THEN 1 ELSE 0 END AS IS_UNIQUE,
C.NUMERIC_PRECISION AS NUMERIC_PRECISION,
C.NUMERIC_SCALE AS NUMERIC_SCALE,
FK.TABLE_NAME AS FOREIGN_KEY_TABLE_NAME,
FK.COLUMN_NAME AS FOREIGN_KEY_COLUMN_NAME

FROM INFORMATION_SCHEMA.COLUMNS C
LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CC
ON C.COLUMN_NAME = CC.COLUMN_NAME
AND C.TABLE_NAME = CC.TABLE_NAME
LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
ON CC.CONSTRAINT_NAME = TC.CONSTRAINT_NAME

LEFT OUTER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
ON TC.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE FC
ON RC.UNIQUE_CONSTRAINT_NAME = FC.CONSTRAINT_NAME

LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE FK
ON FC.COLUMN_NAME = FK.COLUMN_NAME
AND FC.TABLE_NAME = FK.TABLE_NAME
WHERE COLUMNPROPERTY(OBJECT_ID(C.TABLE_SCHEMA + '.' + C.TABLE_NAME), C.COLUMN_NAME, 'IsComputed') = 0
AND TC.CONSTRAINT_TYPE = 'FOREIGN KEY'

2 个答案:

答案 0 :(得分:2)

每列可能有多个约束,因此如果使用包含约束信息的视图连接,则会获得多行,每列约束一列。

另一个原因可能是相同的列和表名出现在不同的模式中。

您可以使用以下查询检查重复项,该查询只会显示出现多次的列:

WITH a as(
    SELECT
    C.COLUMN_NAME AS COLUMN_NAME,
    C.TABLE_NAME AS TABLE_NAME,
    C.CHARACTER_MAXIMUM_LENGTH AS CHARACTER_MAXIMUM_LENGTH,
    C.COLUMN_DEFAULT AS COLUMN_DEFAULT,
    C.DATA_TYPE AS DATA_TYPE,
    C.IS_NULLABLE AS IS_NULLABLE,
    CASE WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE     CONSTRAINT_TYPE = 'PRIMARY KEY'
    AND CONSTRAINT_NAME = CC.CONSTRAINT_NAME) THEN 1 ELSE 0 END AS IS_PRIMARY_KEY,
    CASE WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE     CONSTRAINT_TYPE = 'UNIQUE'
    AND CONSTRAINT_NAME = CC.CONSTRAINT_NAME) THEN 1 ELSE 0 END AS IS_UNIQUE,
    C.NUMERIC_PRECISION AS NUMERIC_PRECISION,
    C.NUMERIC_SCALE AS NUMERIC_SCALE,
    FK.TABLE_NAME AS FOREIGN_KEY_TABLE_NAME,
    FK.COLUMN_NAME AS FOREIGN_KEY_COLUMN_NAME

    FROM INFORMATION_SCHEMA.COLUMNS C
    LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CC
    ON C.COLUMN_NAME = CC.COLUMN_NAME
    AND C.TABLE_NAME = CC.TABLE_NAME
    LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
    ON CC.CONSTRAINT_NAME = TC.CONSTRAINT_NAME

    LEFT OUTER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
    ON TC.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
    LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE FC
    ON RC.UNIQUE_CONSTRAINT_NAME = FC.CONSTRAINT_NAME

    LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE FK
    ON FC.COLUMN_NAME = FK.COLUMN_NAME
    AND FC.TABLE_NAME = FK.TABLE_NAME
    WHERE COLUMNPROPERTY(OBJECT_ID(C.TABLE_SCHEMA + '.' + C.TABLE_NAME), C.COLUMN_NAME,     'IsComputed') = 0
    AND TC.CONSTRAINT_TYPE = 'FOREIGN KEY'
), b as (
    SELECT COLUMN_NAME, TABLE_NAME
      FROM a
    GROUP BY COLUMN_NAME, TABLE_NAME
    HAVING count(*) > 1
)
SELECT a.*
  FROM a JOIN b ON a.COLUMN_NAME = b.COLUMN_NAME AND a.TABLE_NAME = b.TABLE_NAME

CTE a正是您从上面的查询。

答案 1 :(得分:0)

每当您向查询添加JOIN时,该关系可能是一对多关系,从而将结果相乘。你在这里有5 JOIN,因此可能其中一个已陷入此案。

我的猜测是多个约束可以应用于单个列,并且您没有过滤掉足够的可能性来实现不是这样。

关键是要查看您获得的结果,并查看“重复”行中实际不同的内容。我有时使用像SELECT C.*, '--' as [--], CC.*, '--' as [--], ...这样的查询来显示所有连接表的所有列。 (as [--]在Postgres中是as "--",在MySQL中是` - 。)