我有一个数据库A,它包含一个表(CoreTables),用于存储组织用户正在向其发送数据的数据库B中的活动表列表。
我希望能够拥有一个基于集合的查询,该查询只能输出CoreTables中填充了数据的那些表的列表。
动态地,我通常会做类似的事情:
对于CoreTables中的每一行 获取表名 如果表是空的 没做什么 其他 打印表格名称
有没有办法在没有游标或其他动态方法的情况下执行此操作?谢谢你的帮助......
答案 0 :(得分:1)
可能最有效的选择是:
SELECT c.name
FROM dbo.CoreTables AS c
WHERE EXISTS
(
SELECT 1
FROM sys.partitions
WHERE index_id IN (0,1)
AND rows > 0
AND [object_id] = OBJECT_ID(c.name)
);
请注意,由于正在进行的交易,不能保证sys.sysindexes,sys.partitions和sys.dm_db_partition_stats中的计数完全同步。
虽然您可以在数据库的上下文中运行此查询,但您可以按如下方式为不同的数据库执行此操作(同样假设CoreTables在名称中不包含架构):
SELECT c.name
FROM DatabaseA.CoreTables AS c
WHERE EXISTS
(
SELECT 1
FROM DatabaseB.sys.partitions AS p
INNER JOIN DatabaseB.sys.tables AS t
ON p.[object_id] = t.object_id
WHERE t.name = c.name
AND p.rows > 0
);
如果需要对多个数据库执行此操作,这些数据库都包含相同的模式(或者至少重叠在中央CoreTables表中聚合的模式),您可能需要构建一个视图,例如: / p>
CREATE VIEW dbo.CoreTableCounts
AS
SELECT db = 'DatabaseB', t.name, MAX(p.rows)
FROM DatabaseB.sys.partitions AS p
INNER JOIN DatabaseB.sys.tables AS t
ON p.[object_id] = t.[object_id]
INNER JOIN DatabaseA.dbo.CoreTables AS ct
ON t.name = ct.name
WHERE p.index_id IN (0,1)
GROUP BY t.name
UNION ALL
SELECT db = 'DatabaseC', t.name, rows = MAX(p.rows)
FROM DatabaseC.sys.partitions AS p
INNER JOIN DatabaseC.sys.tables AS t
ON p.[object_id] = t.[object_id]
INNER JOIN DatabaseA.dbo.CoreTables AS ct
ON t.name = ct.name
WHERE p.index_id IN (0,1)
GROUP BY t.name
-- ...
GO
现在您的查询效率不高,但不需要将数据库名称硬编码为对象前缀,而是可以:
SELECT name
FROM dbo.CoreTableCounts
WHERE db = 'DatabaseB'
AND rows > 0;
如果执行起来很痛苦,您可以为每个数据库创建一个视图。
答案 1 :(得分:0)
这样的事情?
//
foreach (System.Data.DataTable dt in yourDataSet.Tables)
{
if (dt.Rows.Count != 0) { PrintYourTableName(dt.TableName); }
}
//
答案 2 :(得分:0)
这是一种可以执行此操作的方法,它依赖于系统表,因此AWARE在未来的SQL版本中可能并不总是有效。考虑到这个强烈的警告。
select distinct OBJECT_NAME(id) as tabName,rowcnt
from sys.sysindexes si
join sys.objects so on si.id=si.id
where indid=1 and so.type='U'
您可以在where子句中添加您感兴趣的表和rowcnt< 1
答案 3 :(得分:0)
在SQL Server中,您可以执行以下操作:
SELECT o.name, st.row_count
FROM sys.dm_db_partition_stats st join
sys.objects o
on st.object_id = o.object_id
WHERE index_id < 2 and st.row_count > 0
顺便说一下,这特别不使用OBJECT_ID()或OBJECT_NAME(),因为它们是在当前数据库中计算的。上面的代码继续用于另一个数据库,使用3部分命名。此版本还考虑了多个分区:
SELECT o.name, sum(st.row_count)
FROM <dbname>.sys.dm_db_partition_stats st join
<dbname>.sys.objects o
on st.object_id = o.object_id
WHERE index_id < 2
group by o.name
having sum(st.row_count) > 0