我正在清理数据库,正在寻找一个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
答案 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