SQL Server展平数据-获取有关表和架构的数据

时间:2019-02-19 22:33:40

标签: sql sql-server

我正在尝试获取有关特定给定架构和表名称的数据。我需要的信息是列名,数据类型,是否可为空以及它是外键还是主键。我已经接近以下查询:

SELECT C.COLUMN_NAME, C.DATA_TYPE, C.IS_NULLABLE, CASE WHEN Z.CONSTRAINT_TYPE = 'PRIMARY KEY' THEN 1 ELSE 0 END AS IS_PRIMARY_KEY, 
CASE WHEN Z.CONSTRAINT_TYPE = 'FOREIGN KEY' THEN 1 ELSE 0 END AS IS_FOREIGN_KEY 
FROM INFORMATION_SCHEMA.COLUMNS As C 
OUTER APPLY 
    (SELECT TC.CONSTRAINT_NAME, TC.CONSTRAINT_TYPE FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC 
        JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE As CCU ON CCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME 
        WHERE TC.TABLE_SCHEMA = C.TABLE_SCHEMA AND TC.TABLE_NAME = C.TABLE_NAME 
        AND (TC.CONSTRAINT_TYPE = 'PRIMARY KEY' or TC.CONSTRAINT_TYPE = 'FOREIGN KEY') 
        AND CCU.COLUMN_NAME = C.COLUMN_NAME)
    AS Z 
WHERE C.TABLE_NAME = 'ProductExpert' 
AND C.TABLE_SCHEMA = 'Learning' ORDER BY C.ORDINAL_POSITION

这将收集我需要的数据,但不是“扁平化”的。查看结果图片:

Results

我理想地需要将每列列出1次。在这种情况下,产品ID和OrganizationExpertId将在IS_PRIMARY_KEY和IS_FOREIGN_KEY中用1列出一次。我仍然希望ExpertRoles的返回值都为0。

1 个答案:

答案 0 :(得分:2)

由于连接语法而发生这种情况。您需要按以下方式更改联接:

SELECT 
  C.COLUMN_NAME, 
  C.DATA_TYPE, 
  C.IS_NULLABLE, 
  CASE WHEN PKEY.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS IS_PRIMARY_KEY, 
  CASE WHEN Z.CONSTRAINT_TYPE IS NULL THEN 0 ELSE 1 END AS IS_FOREIGN_KEY 
FROM INFORMATION_SCHEMA.COLUMNS As C 
LEFT OUTER JOIN
    (SELECT TC.CONSTRAINT_NAME, TC.CONSTRAINT_TYPE FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC 
        JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE As CCU ON CCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME 
        WHERE TC.TABLE_SCHEMA = C.TABLE_SCHEMA AND TC.TABLE_NAME = C.TABLE_NAME 
        AND (TC.CONSTRAINT_TYPE = 'PRIMARY KEY' or TC.CONSTRAINT_TYPE = 'FOREIGN KEY') 
        AND CCU.COLUMN_NAME = C.COLUMN_NAME)
    AS PKEY
   ON Z.CONSTRAINT_TYPE = 'PRIMARY KEY'
LEFT OUTER JOIN
    (SELECT TC.CONSTRAINT_NAME, TC.CONSTRAINT_TYPE FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC 
        JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE As CCU ON CCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME 
        WHERE TC.TABLE_SCHEMA = C.TABLE_SCHEMA AND TC.TABLE_NAME = C.TABLE_NAME 
        AND (TC.CONSTRAINT_TYPE = 'PRIMARY KEY' or TC.CONSTRAINT_TYPE = 'FOREIGN KEY') 
        AND CCU.COLUMN_NAME = C.COLUMN_NAME)
    AS FKEY
   ON Z.CONSTRAINT_TYPE = 'FOREIGN KEY'
WHERE C.TABLE_NAME = 'ProductExpert' 
AND C.TABLE_SCHEMA = 'Learning' 
ORDER BY C.ORDINAL_POSITION

或者您也可以将max与group by一起使用

SELECT C.COLUMN_NAME, C.DATA_TYPE, C.IS_NULLABLE, max(CASE WHEN Z.CONSTRAINT_TYPE = 'PRIMARY KEY' THEN 1 ELSE 0 END) AS IS_PRIMARY_KEY, 
max(CASE WHEN Z.CONSTRAINT_TYPE = 'FOREIGN KEY' THEN 1 ELSE 0 END) AS IS_FOREIGN_KEY 
FROM INFORMATION_SCHEMA.COLUMNS As C 
OUTER APPLY 
    (SELECT TC.CONSTRAINT_NAME, TC.CONSTRAINT_TYPE FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC 
        JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE As CCU ON CCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME 
        WHERE TC.TABLE_SCHEMA = C.TABLE_SCHEMA AND TC.TABLE_NAME = C.TABLE_NAME 
        AND (TC.CONSTRAINT_TYPE = 'PRIMARY KEY' or TC.CONSTRAINT_TYPE = 'FOREIGN KEY') 
        AND CCU.COLUMN_NAME = C.COLUMN_NAME)
    AS Z 
WHERE C.TABLE_NAME = 'ProductExpert' 
AND C.TABLE_SCHEMA = 'Learning' 
group by C.COLUMN_NAME, C.DATA_TYPE, C.IS_NULLABLE, C.ORDINAL_POSITION 
ORDER BY C.ORDINAL_POSITION