Не удается вернуть таблицу столбцов, когда в таблице есть только FK?

#sql #sql-server

#sql #sql-сервер

Вопрос:

Когда я выбираю таблицу, в которой ее нет Primary Key , мой запрос ничего не возвращает. Итак, в чем проблема в этом запросе?

Это результат, когда у меня есть pk в моей таблице:

введите описание изображения здесь

И это результат, когда у меня его нет pk в моей таблице:

введите описание изображения здесь

Вот запрос:

 select 
    col.name as [Nom de Colone],
        typ.DATA_TYPE   CASE WHEN typ.DATA_TYPE IN('char', 'nchar', 'varchar', 'nvarchar', 'binary', 'varbinary')AND typ.CHARACTER_MAXIMUM_LENGTH > 0 THEN COALESCE('('   
        CONVERT(varchar, typ.CHARACTER_MAXIMUM_LENGTH)   ')','') ELSE '' END   CASE WHEN typ.DATA_TYPE IN('decimal', 'numeric') THEN COALESCE('('   CONVERT(varchar, typ.NUMERIC_PRECISION)   ','   CONVERT(varchar, typ.NUMERIC_SCALE)   ')','') 
    ELSE '' END AS [Type],
    CASE WHEN col.IS_NULLABLE = 0 THEN 'NOT ' ELSE '' END   'NULL' AS Valeur,
    case when KU.COLUMN_NAME=col.name then cast(1 as bit) else cast(0 as bit) end as [PK],
    case when fk.object_id is not null then cast(1 as bit) else cast(0 as bit) end as [fk],
    case when pk_tab.name is not null then pk_tab.name else ''end as [Ref_Tab_FK],
    case when pk_col.name is not null then pk_col.name else ''end as [Ref_Col_FK]
from sys.tables tab 
    inner join sys.columns col  
        on col.object_id = tab.object_id 
    left outer join sys.foreign_key_columns fk_cols 
        on fk_cols.parent_object_id = tab.object_id and fk_cols.parent_column_id = col.column_id
    left outer join sys.foreign_keys fk  
        on fk.object_id = fk_cols.constraint_object_id left outer join sys.tables pk_tab 
        on pk_tab.object_id = fk_cols.referenced_object_id 
    left outer join sys.columns pk_col
        on pk_col.column_id = fk_cols.referenced_column_id and pk_col.object_id = fk_cols.referenced_object_id 
    inner join INFORMATION_SCHEMA.COLUMNS typ 
        on typ.COLUMN_NAME=col.name and tab.name=typ.TABLE_NAME 
    inner join INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC 
    on tc.TABLE_NAME=typ.TABLE_NAME and TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU
        ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
        AND TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME     
where tab.name='TABLE_NAME' 
order by col.column_id
  

Ответ №1:

Поскольку вы вводите INNER JOIN с ограничением ПЕРВИЧНОГО КЛЮЧА, как указано ниже, в результирующем наборе возвращаются только таблицы с ПЕРВИЧНЫМ КЛЮЧОМ.

     inner join INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC 
    on tc.TABLE_NAME=typ.TABLE_NAME and TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU
        ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
        AND TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME     
  

Если вы измените их на LEFT OUTER JOIN , вы получите таблицы без ПЕРВИЧНОГО КЛЮЧА и только ВНЕШНИЙ КЛЮЧ

     LEFT OUTER join INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC 
    on tc.TABLE_NAME=typ.TABLE_NAME and TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
    LEFT OUTER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU
        ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
        AND TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME  
  

Комментарии:

1. но когда у меня есть два pk, я нахожу проблему, она возвращает столбцы в два раза

2. Я думаю, что вы вводите соединение дважды для получения pk: left outer join sys.columns pk_col и INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC on tc.TABLE_NAME=typ.TABLE_NAME and TC.CONSTRAINT_TYPE = 'PRIMARY KEY' . Из-за этого вы получаете столбцы PK дважды