1

特定のデータベースの列に関する特定の重要な情報を提供するクエリを作成しようとしていますが、これまでのところ、クエリが奇妙な結果を返すようです! 列のサイズ、null 可能性、一意性などについて知る必要があります。

では、なぜ列ごとに複数の結果が得られるのでしょうか?

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'
4

2 に答える 2

2

おそらく列ごとに複数の制約があるため、制約情報を含むビューと結合すると、列の制約ごとに 1 行ずつ、複数の行が得られます。

別の理由として、同じ列とテーブル名が異なるスキーマに表示されることが考えられます。

次のクエリを使用して重複を確認できます。これは、列が複数回表示されていることを示しています。

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

CTEaはまさに上記のクエリです。

于 2013-08-30T16:15:01.757 に答える
0

クエリにa を追加するJOINと、その関係が 1 対多になる可能性があり、結果が乗算されます。ここには 5 つJOINの s があるので、おそらくそのうちの 1 つがこのケースに該当します。

私の推測では、複数の制約が単一の列に適用される可能性があり、そうでない可能性を十分に除外していません。

重要なのは、得られた結果を見て、「重複」行で実際に何が違うかを確認することです。SELECT C.*, '--' as [--], CC.*, '--' as [--], ...結合されたすべてのテーブルのすべての列を表示するようなクエリを使用することがあります。( Postgres では 、MySQL では `--` になります。as [--])as "--"

于 2013-08-30T16:18:52.193 に答える