Перечисление индексов и ограничений

10

Я смотрю на базу данных SQL Server для приложения, которое я унаследовал. Я не изучал SQL Server около 10 лет, поэтому, пожалуйста, потерпите меня.

У таблицы базы данных, на которую я смотрю, есть bigint NOT NULLстолбец с именем id, но когда я проверяю наличие ограничений, я не вижу ни одной, и то же самое верно для всех таблиц базы данных.

Прав ли я, предполагая, что в этих таблицах нет первичного ключа и нет индексации (кластеризованной или некластеризованной)?

Я выполнил следующие запросы, и результаты, по-видимому, подтверждают мое подозрение:

//**returns 0**
select count(*) from INFORMATION_SCHEMA.TABLE_CONSTRAINTS;

//**returns no rows**
select * from sys.indexes
where object_id = (select object_id from sys.objects where name = 'NAME-OF-TABLE');

//**returns all tables in database**
SELECT name
FROM sys.tables 
WHERE OBJECTPROPERTY(object_id,'IsIndexed') = 0;
Али Хайдер
источник

Ответы:

9

Эти два вопроса могут вам помочь. Первый перечислит все таблицы и индексы этих таблиц в вашей базе данных. Если таблица не отображается в списке, для нее не определены индексы. Эти запросы предполагают версию SQL Server 2005 или более новую.

SELECT 
    IndexName = QUOTENAME(I.name), 
    TableName =
        QUOTENAME(SCHEMA_NAME(T.[schema_id])) + 
        N'.' + QUOTENAME(T.name), 
    IsPrimaryKey = I.is_primary_key
FROM sys.indexes AS I
INNER JOIN sys.tables AS T
    ON I.[object_id] = T.[object_id]
WHERE
    I.type_desc <> N'HEAP'
ORDER BY 
    TableName ASC, 
    IndexName ASC;

Второй запрос сообщит для каждой таблицы столбец идентификаторов, если таковой имеется в каждой таблице в вашей базе данных.

SELECT
    TableName =
        QUOTENAME(SCHEMA_NAME(T.[schema_id])) + 
        N'.' + QUOTENAME(T.name), 
    IdentityColumn = COALESCE(QUOTENAME(C.name), N'No identity column')
FROM sys.tables AS T
LEFT OUTER JOIN sys.columns AS C
    ON T.[object_id] = C.[object_id]
    AND C.is_identity = 1
ORDER BY
    TableName ASC;

Чтобы ограничить запросы конкретной таблицей, добавьте WHEREпредложение, подобное:

WHERE T.name = N'NAME-OF-TABLE'
Джереми
источник
2

Нет, что-то не так.

Проверка sys.indexesдолжна возвращать строку, даже если ваша таблица не имеет индексов. У кучи все еще есть запись sys.indexesс type_desc'HEAP' и type0.

Я думаю, что вам, вероятно, нужно убедиться, что вы находитесь в правильном контексте базы данных, поскольку OBJECT_ID()и sys.objectsспецифичны для базы данных.

Попробуй это:

USE MyDatabase

SELECT *
FROM sys.indexes
WHERE object_id = OBJECT_ID('schema.MyTableName')
JNK
источник
1

Я не уверен, что вас интересуют все ограничения, но INFORMATION_SCHEMA.TABLE_CONSTRAINTS, похоже, не возвращает ограничения DEFAULT - TABLE_CONSTRAINTS (Transact-SQL)

ПРОВЕРИТЬ, УНИКАЛЬНЫЙ, ПЕРВИЧНЫЙ КЛЮЧ, ИНОСТРАННЫЙ КЛЮЧ

Этот запрос будет делать простой подсчет против DMV sys.objects:

select COUNT(*)
from sys.objects o
where o.type_desc like '%CONSTRAINT%';

Если вы заинтересованы в перечислении таблиц, вы можете запустить что-то вроде этого:

select distinct
   o.object_id
 , QUOTENAME(s.name) + '.' + QUOTENAME(o.name) as [object_name]
 , o.type_desc
 , case when dc.parent_object_id is null then 'No' else 'Yes' end as has_default_constraint
 , case when cc.parent_object_id is null then 'No' else 'Yes' end as has_check_constraint
 , case when fk.parent_object_id is null then 'No' else 'Yes' end as has_foreing_key
 , case when kc.parent_object_id is null then 'No' else 'Yes' end as has_primary_key
from sys.objects o
inner join sys.schemas s on s.schema_id = o.schema_id
left outer join sys.default_constraints dc on dc.parent_object_id = o.object_id and dc.schema_id = o.schema_id
left outer join sys.check_constraints cc on cc.parent_object_id = o.object_id and cc.schema_id = o.schema_id
left outer join sys.foreign_keys fk on fk.parent_object_id = o.object_id and fk.schema_id = o.schema_id
left outer join sys.key_constraints kc on kc.parent_object_id = o.object_id and kc.schema_id = o.schema_id
where o.is_ms_shipped = 0
  and o.type = 'U'
order by [object_name];

Этот должен дать вам информацию о ваших индексах:

select o.name
 , i.*
from sys.objects o
inner join sys.indexes i on i.object_id = o.object_id
where o.is_ms_shipped = 0
  and i.object_id > 100
  and i.index_id > 0
order by o.name
   , i.index_id;
  • Index_Id = 0 - HEAP (не будет отображаться)
  • Index_Id = 1 - CLUSTERED
  • Index_Id> 1 - НЕКЛЮЧЕНО
DenisT
источник
не могли бы вы объяснить, почему у вас есть object_id > 100?
brianc
@ bluevoodoo1 - не обязательно, но <100 являются системными объектами, но, поскольку использование o.is_ms_shipped = 0, не должно включать их в любом случае. Просто играть безопасно, вот и все
DenisT