提问人:Daniel Hudsky 提问时间:6/8/2017 最后编辑:Stephen KingDaniel Hudsky 更新时间:11/18/2023 访问量:57
我需要一种方法来查看我的哪些数据库表不为空,但我在语法上有点挣扎
I need a way to see which of my db tables are not empty, but I am strugling with the syntax a bit
问:
我使用了一个引用表,该表通过 schemaid 引用架构(表名)。 我需要从 T(table) 运行 SELECT count(),其中 count() > 0 但仅适用于名称中带有 CORE:Table 的表。我认为可以通过声明 @schemaset然后使用 while 循环来处理它来替换(表)。我更习惯于FOR循环,但MSSQL似乎没有。
DECLARE @schemaset VARCHAR
WHILE @schemaset in (select schemaId from arschema where name like 'CORE:Table%')
BEGIN
select COUNT(*) from T(@schemaset)where FIELD1 IS NOT NULL
END
查询运行,但表示已成功完成。我尝试打印以查看结果,但抱怨错误。
那么,如何对一组特定表进行完整/空检查呢?
答:
1赞
pmbAustin
6/8/2017
#1
下面是一个将返回所有空表的 SQL 示例:
-- All Empty Tables
CREATE TABLE #counts (table_name sysname,row_count int)
EXEC sp_MSForEachTable @command1='INSERT #counts (table_name, row_count) SELECT ''?'', COUNT(*) FROM ?'
SELECT table_name AS EmptyTables, row_count
FROM #counts
WHERE row_count = 0
ORDER BY table_name
DROP TABLE #counts
GO
另一种策略不依赖于未记录的“sp_MSForEachTable”存储过程,并允许您筛选要检查的表,如下所示:
DECLARE @sql nvarchar(max);
CREATE TABLE #Counts (Table_Name sysname, Row_Count int);
SET @sql = N'';
SELECT @sql += N'INSERT INTO #Counts (Table_Name, Row_Count) SELECT ''' + TABLE_NAME +
N''', COUNT(1) FROM ' + QUOTENAME(TABLE_NAME) + N'; '
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA = 'dbo' AND TABLE_NAME LIKE N'A%'
PRINT @sql;
EXEC(@sql);
SELECT * FROM #Counts
DROP TABLE #Counts
SELECT 语句将表列表筛选为仅“dbo”架构中的表,以及以字母“A”开头的表。您可以根据需要进行更改,筛选所需的任何表。
基本上,此代码所做的是为每个表构建一系列 INSERT 语句,将 COUNT 和表名插入到临时表中。你可以按摩它来做任何你想做的事情......这纯粹是一个例子。
评论
0赞
Daniel Hudsky
6/8/2017
这个解决方案也有效,谢谢pmbAustin。但是,我还需要包含架构表中的“名称”,其中映射了 schemaid 和名称。这就是为什么我需要 while 循环,它允许我使用表名的前 3 个字符来限定查询。
0赞
pmbAustin
6/8/2017
该要求并不否定此...只需更改 SELECT 语句中的 FROM 和 WHERE 即可满足您的需求。您仍然不需要任何 WHILE 循环。
2赞
Sean Lange
6/8/2017
#2
为此,您不需要循环或动态 sql。这将使用单个 select 语句返回所有具有零行的表。
SELECT TableName = t.name
, TableRowCount = SUM(p.rows)
, SchemaName = s.name
FROM sys.partitions AS p
INNER JOIN sys.tables AS t ON p.object_id = t.object_id
INNER JOIN sys.schemas AS s ON t.schema_id = s.schema_id
WHERE p.index_id IN (0, 1) -- heap or clustered index
group by t.name
, s.name
having SUM(p.rows) = 0
order by t.name
评论
0赞
SqlZim
6/8/2017
如果同一个表名位于两个不同的架构中,或者可能希望包含架构名称,可能还需要分组依据。object_id
1赞
Sean Lange
6/8/2017
--EDIT-- 添加了模式名称,以防万一您在不同的模式中有多个具有相同名称的对象。感谢@SqlZim的建议。
0赞
TechGuy
11/18/2023
#3
这是对上述逻辑的调整,出于实际原因,您的输出需要架构(因为可能存在多个架构),如果存在 dbo 以外的架构,则上述逻辑会中断
DECLARE @sql nvarchar(max);
CREATE TABLE #Counts (Table_Name sysname, Row_Count int);
SET @sql = N'';
SELECT @sql += N'INSERT INTO #Counts (Table_Name, Row_Count) SELECT ''' +
TABLE_SCHEMA +'.'+ TABLE_NAME +
N''', COUNT(*) FROM ' + QUOTENAME(TABLE_SCHEMA) + '.'
QUOTENAME(TABLE_NAME) + N'; '
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA LIKE N'%' AND
TABLE_NAME LIKE N'%'
ORDER BY TABLE_NAME
PRINT @sql;
EXEC(@sql);
SELECT * FROM #Counts
DROP TABLE #Counts
评论