选择所有空数据库

时间:2019-02-21 17:36:12

标签: sql sql-server tsql

我正在清理数据库,正在寻找一个t-sql查询,该查询将向我显示所有没有任何表或视图的数据库。

此问题:https://dba.stackexchange.com/questions/114958/list-all-tables-from-all-user-databases/230411#230411

我有一个查询,该查询将返回具有0条记录的表,但它会丢失那些没有任何表的数据库。

If Exists (Select * From tempdb.dbo.sysobjects o Where o.xtype in ('U') And o.id = object_id (N'tempdb..#temptable')) Begin Drop Table #temptable End


DECLARE @src NVARCHAR(MAX), @sql NVARCHAR(MAX);

SELECT @sql = N'', @src = N' UNION ALL 
SELECT ''$d'' as ''database'', 
    s.name COLLATE SQL_Latin1_General_CP1_CI_AI as ''schema'',
    t.name COLLATE SQL_Latin1_General_CP1_CI_AI as ''table'' ,
    ind.rows as record_count
  FROM [$d].sys.schemas AS s
  INNER JOIN [$d].sys.tables AS t ON s.[schema_id] = t.[schema_id]
  INNER JOIN [$d].sys.sysindexes AS ind ON t.[object_id] = ind.[id]
  --where ind.indid < 2';

SELECT @sql = @sql + REPLACE(@src, '$d', name)
  FROM sys.databases
  WHERE database_id > 4
    AND [state] = 0
    AND HAS_DBACCESS(name) = 1;

SET @sql = STUFF(@sql, 1, 10, CHAR(13) + CHAR(10));


create table #temptable  (
database_name varchar(max) null,
schema_name varchar(max) null,
table_name varchar(max) null,
record_count int null
)

insert into #temptable
EXEC sys.sp_executesql @sql;

select * from #temptable where record_count = 0 order by 1,2,3,4

3 个答案:

答案 0 :(得分:0)

注意:这应该可以工作(脚本对我来说很好),但是我的系统中没有任何没有表的数据库,因此在这方面未经测试。

我更新了脚本,以对索引和表的系统表进行LEFT JOIN。 INNER JOIN要求这些记录中存在记录,并且如果您正在寻找没有表的DB,则INNER JOIN将永远不会返回这些记录。

我也更新了您的最终选择,并记录了如果要保留具有0个重新记录的表以及不包含或不包含表的DB时如何获得结果。

If Exists (Select * From tempdb.dbo.sysobjects o Where o.xtype in ('U') And o.id = object_id (N'tempdb..#temptable')) Begin Drop Table #temptable End


DECLARE @src NVARCHAR(MAX), @sql NVARCHAR(MAX);

SELECT @sql = N'', @src = N' UNION ALL 
SELECT ''$d'' as ''database'', 
    s.name COLLATE SQL_Latin1_General_CP1_CI_AI as ''schema'',
    t.name COLLATE SQL_Latin1_General_CP1_CI_AI as ''table'' ,
    ind.rows as record_count
  FROM [$d].sys.schemas AS s
  LEFT JOIN [$d].sys.tables AS t ON s.[schema_id] = t.[schema_id]
  LEFT JOIN [$d].sys.sysindexes AS ind ON t.[object_id] = ind.[id]
  --where ind.indid < 2';

SELECT @sql = @sql + REPLACE(@src, '$d', name)
  FROM sys.databases
  WHERE database_id > 4
    AND [state] = 0
    AND HAS_DBACCESS(name) = 1;

SET @sql = STUFF(@sql, 1, 10, CHAR(13) + CHAR(10));


create table #temptable  (
database_name varchar(max) null,
schema_name varchar(max) null,
table_name varchar(max) null,
record_count int null
)

insert into #temptable
EXEC sys.sp_executesql @sql;

select * 
FROM #temptable 
WHERE record_count = 0 -- this returns 0 counts in tables (remove if you dont want dbs with tables)
OR table_name IS NULL  -- this should return recors with DBS but no table names
ORDER by 1,2,3,4

答案 1 :(得分:0)

要获取数据库中表的数量,可以发出以下命令:

declare @howmany int;

select @howmany=count(*) from sys.objects where type='U'
Select 'There are '+cast(@howmany as varchar(10)) +' tables in the database.';

答案 2 :(得分:0)

@Brad-感谢您的帮助和建议。 我接受了您的建议并对此进行了扩展。我将表类型添加到union all脚本中,然后在temp表的where子句中添加了一个子选择,它给了我想要的东西。

If Exists (Select * From tempdb.dbo.sysobjects o Where o.xtype in ('U') And o.id = object_id (N'tempdb..#temptable')) Begin Drop Table #temptable End


DECLARE @src NVARCHAR(MAX), @sql NVARCHAR(MAX);

SELECT @sql = N'', @src = N' UNION ALL 
SELECT ''$d'' as ''database'', 
    s.name COLLATE SQL_Latin1_General_CP1_CI_AI as ''schema'',
    t.name COLLATE SQL_Latin1_General_CP1_CI_AI as ''table'' ,
    t.type,
    ind.rows as record_count
    FROM [$d].sys.schemas AS s
    LEFT JOIN [$d].sys.tables AS t ON s.[schema_id] = t.[schema_id]
    LEFT JOIN [$d].sys.sysindexes AS ind ON t.[object_id] = ind.[id]
 '

SELECT @sql = @sql + REPLACE(@src, '$d', name)
  FROM sys.databases
  WHERE database_id > 4
    AND [state] = 0
    AND HAS_DBACCESS(name) = 1;

SET @sql = STUFF(@sql, 1, 10, CHAR(13) + CHAR(10));


create table #temptable  (
database_name varchar(max) null,
schema_name varchar(max) null,
table_name varchar(max) null,
table_type varchar(max) null,
record_count int null
)

insert into #temptable
EXEC sys.sp_executesql @sql;


select * 
FROM #temptable 
WHERE 
database_name not in (Select database_name from #temptable where table_type = 'u')
ORDER by 1,2,3,4