我有一个相当简单的查询,为了删除临时表,我开始对其进行修改,因为我们在许多不同的系统和客户端上都存在并发问题。
现在,简单的解决方案是将查询分解为多个单独的查询,以复制SQL之前所做的事情。
我正在尝试找到一种方法来将动态SQL查询的结果作为列值返回。新查询非常简单,它会在系统对象中查找具有特定格式和输出的所有表。我所缺少的是,对于每条记录,我都需要在每个表上输出动态查询的结果。
查询:
SELECT [name] as 'TableName'
FROM SYSOBJECTS WHERE xtype = 'U'
AND (CHARINDEX('_PCT', [name]) <> 0
OR CHARINDEX('_WHT', [name]) <> 0)
所有这些表都有一个称为Result
的公共列,该列为浮点数。我想做的是返回某个通用的WHERE
子句下的该列的计数,该子句也将适用于所有表。
所需查询(我知道这是无效的)将是:
SELECT [name] as 'TableName',
sp_executesql 'SELECT COUNT(*) FROM ' + [name] + ' WHERE Result > 0 OR (Result < 139 AND CurrentIndex < 15)' as 'ResultValue'
FROM SYSOBJECTS WHERE xtype = 'U'
AND (CHARINDEX('_PCT', [name]) <> 0
OR CHARINDEX('_WHT', [name]) <> 0)
以前很容易。我们有一个包含2列的临时表,并且首先填充了表名。然后,我们迭代临时表并执行动态sql,并在OUTPUT
变量中返回值,然后简单地更新临时表的记录,最后返回该表。
我尝试了标量函数,但是它不支持动态SQL,所以它不起作用。我宁愿不为13,000〜个表创建13,000〜个不同的查询。
我尝试使用参考表并使用触发器来更新状态,但是这会使系统速度大大降低。平均表插入和删除2千8百万条记录。原始的临时表查询由于建立了很好的索引而只花了5-6分钟的时间来执行,而现在我们达到25-30分钟。
除了查询表列表然后客户端一一查询每个表以了解其状态之外,还有其他解决方案吗?
如果某些新功能现在可用,我们正在使用SQL Server 2017
答案 0 :(得分:1)
您可以根据需要使用此脚本(在SQL Server 2016中经过测试)。
已更新:由于结果现在是单个集合,因此现在应该可以使用。
EXEC sp_msforeachtable
@precommand = 'CREATE TABLE ##Statistics
(TableName varchar(128) NOT NULL,
NumOfRows int)',
@command1 ='INSERT INTO ##Statistics (TableName, NumOfRows)
SELECT ''?'' Table_Name, COUNT(*) Row_Count FROM ? WHERE Result > 0 OR (Result < 139 AND CurrentIndex < 15)',
@postcommand = 'SELECT TableName, NumOfRows FROM ##Statistics;
DROP TABLE ##Statistics'
,@whereand = ' And Object_id In (Select Object_id From sys.objects
Where name like ''%_PCT%'' OR name like ''%_WHT%'')'
有关 sp_msforeachtable 的详细信息,请访问this链接