web-dev-qa-db-ja.com

インデックスと制約の一覧表示

継承したアプリケーションのSQL Serverデータベースを見ています。約10年間SQL Serverを調べていませんので、ご容赦ください。

私が見ているデータベーステーブルには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;
10
ali haider

これらの2つのクエリが役立つ場合があります。 1つ目は、データベース内のすべてのテーブルとそれらのテーブルのインデックスを一覧表示します。テーブルがリストに表示されない場合は、インデックスが定義されていません。これらのクエリは、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;

2番目のクエリは、データベースの各テーブルに存在する場合、各テーブルのID列を報告します。

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'
9
Jeremy

いいえ、何かが間違っています。

_sys.indexes_のチェックでは、テーブルにインデックスがない場合でも行が返されます。ヒープの_sys.indexes_には、type_desc_が「HEAP」、typeが0のレコードが残っています。

OBJECT_ID()と_sys.objects_はデータベース固有なので、おそらく正しいデータベースコンテキストにいることを確認する必要があると思います。

これを試して:

_USE MyDatabase

SELECT *
FROM sys.indexes
WHERE object_id = OBJECT_ID('schema.MyTableName')
_
2
JNK

すべての制約に興味があるかどうかはわかりませんが、INFORMATION_SCHEMA.TABLE_CONSTRAINTSがDEFAULT制約を返さないようです TABLE_CONSTRAINTS(Transact-SQL)

チェック、一意、主キー、外部キー

このクエリは、sys.objects DMVに対して単純なカウントを行います。

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-不要
1
DenisT