Непонятное поведение - информационная схема SQL Server и столбцы, созданные с помощью мастера - PullRequest
0 голосов
/ 10 декабря 2018

РЕДАКТИРОВАТЬ: я попробовал этот код, часть того, что упомянул пользователь, и он возвращает поля правильно.

SELECT * FROM INFORMATION_SCHEMA.TABLES 
        JOIN INFORMATION_SCHEMA.COLUMNS on 
        INFORMATION_SCHEMA.TABLES.TABLE_NAME = 
        INFORMATION_SCHEMA.COLUMNS.TABLE_NAME
WHERE INFORMATION_SCHEMA.TABLES.TABLE_NAME = 'myTable'

В первом запросе есть что-то, что работает с некоторыми базами данных, но не с другими


EDIT2:

Я попытался настроить Profilerтрассировка, чтобы проверить создание столбцов с помощью мастера, как предложил пользователь.Он использует ту же схему, по-видимому.

ALTER TABLE dbo.table1 ADD
field2 nchar(10) NULL

Я работаю с SQL Server 2014 и создавал базы данных с помощью мастера, я имею в виду не по коду, а с помощью пользовательского интерфейса.

Затем,Я попытался получить информацию метаданных относительно столбцов их таблиц .. и никаких результатов не возвращается.Я запрашиваю INFORMATION_SCHEMA.

Я пытался использовать тот же запрос для баз данных, которые я создал с помощью кода, и он работает нормально, возвращает столбцы и их значения и т. Д.

I 'Мы пытались найти его через Интернет, но, похоже, не можем придумать ничего подходящего для подобных случаев.Я думаю, что это немного странно, что это имеет значение для столбцов, созданных кодом и с помощью пользовательского интерфейса. Если кто-то знает, почему что-то подобное может произойти, или кажется знакомым, я был бы признателен за это:)

Вот код, который я использую для получения метаданных столбцов:

USE 'database'
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 
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

Результаты:

  • Если таблица и столбцы были созданы кодом -> возвращает всестолбцы и их метаданные для данной базы данных

  • Если таблица и столбцы были созданы с использованием пользовательского интерфейса и окон -> ничего не возвращает, просто пустой набор результатов

1 Ответ

0 голосов
/ 10 декабря 2018

Правильные объединения изменяют природу запроса, и их всегда можно переписать, изменив порядок таблиц.Избегайте правильных объединений .... попробуйте вместо этого:

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, в которой почти наверняка есть строки.

Таким образом, в исходном запросе используется неправильный максимумтаблица приоритетов, которая скрыта из-за правильных соединений.Работающий запрос использует разумную таблицу в качестве своей базовой таблицы и не использует правильные объединения.

...