2011-01-20 13 views
2

SQL Serverのインスタンス上にあるテーブルの数はどのようにして確認できますか?何を求めていることは、特定のSQL Serverインスタンス上のすべてのデータベース間で存在してどのように多くのテーブルを決定する方法であれば、私は、あなたがする必要がある、(how to count number of tables/views/index in my databaseから)select count(*) from sysobjects where type = 'U' を使用して、単一のスキーマのSQL Serverのインスタンスにあるテーブルの数

答えて

4

あなたは「スキーマ」という言葉を使用していますが、実際にはすべての「データベース」にまたがってテーブルを数えたいと思っています。

declare @t table (
    DBName sysname, 
    NumTables int 
) 

insert into @t 
    exec sp_MSforeachdb N'select ''?'', count(*) 
           from [?].dbo.sysobjects 
           where type = ''U''' 

select DBName, NumTables 
    from @t 
    where DBName not in ('distribution','master','model','msdb','tempdb') 
    order by DBName 

select SUM(NumTables) as TotalTables 
    from @t 
    where DBName not in ('distribution','master','model','msdb','tempdb') 
+0

master、msdbなどの既定のデータベースは含まれませんか? – Thomas

+0

@トーマス:そうです。もしそれらが望ましくないなら、それらは簡単にWHERE節で除外することができます。私は私の答えを改めるつもりです。 –

0
Select Count(*) 
From INFORMATION_SCHEMA.TABLES 
Where TABLE_TYPE = 'BASE TABLE' 

をそれを得ることができます各データベースを循環します。一つの方法は、次のようになります。

Declare @Databases Cursor 
Declare @DbName as nvarchar(64) 
Declare @SQL nvarchar(max) 
Declare @BaseSQL nvarchar(max) 
Declare @Count int 
Declare @TotalCount int 

Set @Databases = Cursor Fast_Forward For 
    select [name] 
    from master..sysdatabases 
    where [name] Not In('master','model','msdb','tempdb') 

Open @Databases 
Fetch Next From @Databases Into @DbName 

Set @BaseSQL = 'Select @Count = Count(*) 
        From DatabaseName.INFORMATION_SCHEMA.TABLES 
        Where TABLE_TYPE = ''BASE TABLE''' 

Set @TotalCount = 0 
While @@Fetch_Status = 0 
Begin 
    Set @Count = 0 
    Set @SQL = Replace(@BaseSQL, 'DatabaseName', QuoteName(@DbName)) 

    exec sp_executesql @SQL, N'@Count int OUTPUT', @Count OUTPUT 

    Set @TotalCount = @TotalCount + @Count 

    Fetch Next From @Databases Into @DbName 
End 

Close @Databases 
Deallocate @Databases 

Select @TotalCount 

このソリューションは、このようなsp_MSforeachdbなど任意の文書化されていない機能を使用しないという利点があるが、それは明らかに、より冗長です。

+0

これは現在のスキーマ内のテーブルの数、全体ではなく、インスタンスを取得します。 – thefroatgt

+0

@thefroatgt - インスタンス内のすべてのデータベースを対象としていたことが明確ではありませんでした。しかし、私は解決策を提供しました。 – Thomas

+0

+1データベース名に ']'文字が含まれている場合にだけ、 'quotename(@DbName)'を使うべきです。 –

1

オプション隠され、文書化されていないsp_MSforeachdbパフォーマンスに

declare @sql nvarchar(max) 

select @sql = coalesce(@sql + ' + ', '') + REPLACE(' 
(select count(*) 
from ::DB::.sys.objects 
where is_ms_shipped = 0 
    and type_desc = ''USER_TABLE'')', '::DB::', QUOTENAME(name)) 
from master.sys.databases 
where owner_sid != 0x01 

select @sql = 'select ' + @sql 

exec (@sql) -- returns a single count of all [user] tables in the instance 

>

ノートを使用しません。 物事のより大きな体系では重要ではありませんが、興味深いことに、誰かがそれを時間に縛られています。ここでは、string-concatメソッドに対して一時テーブル(内部的にカーソルを使用する)を通過するms_foreachdbアプローチの比較を示します。

-- all the variables that we will use 
declare @i int -- loop variable 
declare @sql nvarchar(max) -- statement var used for 1st approach 
declare @t table (DBName sysname, NumTables int) -- table used for 2nd approach 

-- init plan cache and buffers 
dbcc freeproccache dbcc dropcleanbuffers 

print convert(varchar(30), getdate(), 121) 

set @i = 0 while @i < 5 begin 
set @sql = null 
select @sql = coalesce(@sql, '') + REPLACE(' 
    select @c = @c + count(*) 
    from ::DB::.sys.objects 
    where is_ms_shipped = 0 
    and type_desc = ''USER_TABLE''', '::DB::', QUOTENAME(name)) 
from master.sys.databases 
where owner_sid != 0x01 
select @sql = 'set nocount on declare @c int set @c = 0 ' + @sql + ' select @c' 
exec (@sql) 

-- clear plan cache and buffers after each run 
dbcc freeproccache dbcc dropcleanbuffers set @i = @i + 1 
end 

print convert(varchar(30), getdate(), 121) 

set @i = 0 while @i < 5 begin 
insert into @t 
    exec sp_MSforeachdb N'select ''?'', count(*) 
      from [?].dbo.sysobjects 
      where type = ''U''' 

select SUM(NumTables) as TotalTables 
    from @t 
    where DBName not in ('distribution','master','model','msdb','tempdb') 

-- unfortunately this is required 
delete from @t 

-- clear plan cache and buffers after each run 
dbcc freeproccache dbcc dropcleanbuffers set @i = @i + 1 
end 

print convert(varchar(30), getdate(), 121) 

それぞれの5回の呼び出し(ループ反復)で得られた結果。 YMMV

start     : 2011-01-21 14:21:45.180 
end of string-concat : 2011-01-21 14:21:57.497 (12.317) 
end of sp_msforeachdb : 2011-01-21 14:22:13.937 (16.440) 

これは一時テーブルは、第2の手法の各反復の間に空にしなければならないので、それは合計時間に寄与することに留意しなければなりません。それは重要ではないはずです

1

ここでは、ドキュメント化されていない関数を使用しない回答があり、SQL Server 2005、2008および2008R2で動作します。この回答は、データベース全体でステートメントを実行するための小さな変更で使用できます。


DECLARE @sql varchar(200), @dbname sysname, @dbid smallint; 

CREATE table #alltables 
(dbname sysname, 
[number of tables] int); 

SELECT top 1 @dbname = name, @dbid = database_id 
FROM sys.databases 
where database_id > 4; 

WHILE (@dbname is not null) 
begin 

    -- the statement below could contain any valid select statement 
    set @sql = 'use ' + @dbname + '; insert into #alltables select ''' + @dbname + ''', count(*) from sys.tables'; 

    EXEC (@sql) 

    set @dbname = null; 

    SELECT top 1 @dbname = name, @dbid = database_id 
    FROM sys.databases 
    where database_id > @dbid; 

end; 

select * FROM #alltables; 
SELECT sum([number of tables]) "Total Number of Tables in all user databases" from #alltables; 

drop table #alltables; 
関連する問題