Правильные объединения изменяют природу запроса, и их всегда можно переписать, изменив порядок таблиц.Избегайте правильных объединений .... попробуйте вместо этого:
SELECT infSch.TABLE_CATALOG,
infSch.TABLE_NAME,
sysCols.name,
infSch.ORDINAL_POSITION,
sysCols.is_nullable,
infSch.DATA_TYPE,
infSch.CHARACTER_MAXIMUM_LENGTH,
sysCols.is_identity,
IIF(infSchCons.CONSTRAINT_TYPE = 'PRIMARY KEY', 1, 0),
IIF(infSchCons.CONSTRAINT_TYPE = 'FOREIGN KEY', 1, 0),
IIF(infSchCons.CONSTRAINT_TYPE = 'UNIQUE', 1, 0),
IIF(infSchCons.CONSTRAINT_TYPE = 'CHECK', 1, 0)
FROM sys.columns as sysCols
LEFT JOIN INFORMATION_SCHEMA.COLUMNS as infSch on sysCols.name =
infSch.COLUMN_NAME
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as infSchCons on
infSch.TABLE_NAME = infSchCons.TABLE_NAME
Этот запрос НЕ ограничивает результаты только теми, где существуют ограничения.
Попробуйте сравнить их:
select count(*) from (
SELECT
infSchCons.*
FROM sys.columns as sysCols
right JOIN INFORMATION_SCHEMA.COLUMNS as infSch on sysCols.name = infSch.COLUMN_NAME
right JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as infSchCons on infSch.TABLE_NAME = infSchCons.TABLE_NAME
) x
;
select count(*) from (
SELECT
infSchCons.*
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS infSchCons
left JOIN INFORMATION_SCHEMA.COLUMNS AS infSch ON infSchCons.TABLE_NAME = infSch.TABLE_NAME
left JOIN sys.columns AS sysCols ON infSch.COLUMN_NAME = sysCols.name
) x
;
Последний запрос - это перезапись оригинального предложения from, и здесь легче (на мой взгляд) увидеть, что вы должны иметь ограничения для любой возвращаемой строки.
EDIT
Был задан вопрос, почему определенный запрос не работал в некоторых базах данных.
Этот запрос использует RIGHT OUTER JOINS
В связи с тем, чтоОперация join tyupe работает, она изменяет приоритет таблиц - и это может сбивать с толку
Поскольку все правильные объединения могут быть «обращены», когда вы выполняете эквивалентный запрос (к оригиналу) с предложением from, например так:
FROM <b>INFORMATION_SCHEMA.TABLE_CONSTRAINTS</b> AS infSchCons
left JOIN INFORMATION_SCHEMA.COLUMNS AS infSch ON infSchCons.TABLE_NAME = infSch.TABLE_NAME
left JOIN sys.columns AS sysCols ON infSch.COLUMN_NAME = sysCols.name
Таким образом, таблица с наивысшим приоритетом равна INFORMATION_SCHEMA.TABLE_CONSTRAINTS
и , если в этой таблице нет строк, запрос не вернет никаких данных .
Во втором редактировании вопроса есть запрос, который работает:
SELECT
*
FROM <b>INFORMATION_SCHEMA.TABLES</b>
JOIN INFORMATION_SCHEMA.COLUMNS ON INFORMATION_SCHEMA.TABLES.TABLE_NAME =
INFORMATION_SCHEMA.COLUMNS.TABLE_NAME
WHERE INFORMATION_SCHEMA.TABLES.TABLE_NAME = 'myTable'
И: это «работает», потому что таблица с наивысшим приоритетом равна INFORMATION_SCHEMA.TABLES
, в которой почти наверняка есть строки.
Таким образом, в исходном запросе используется неправильный максимумтаблица приоритетов, которая скрыта из-за правильных соединений.Работающий запрос использует разумную таблицу в качестве своей базовой таблицы и не использует правильные объединения.