我遇到了一堵墙,在几个表中编译行更新和新行,以保存在另一个表中进行趋势分析。我知道游标可以很容易地实现这一点,但对我来说更复杂的是如何保存表名和结果。生产数据库有几个我感兴趣的表,每一行都有时间戳。
我的stats数据库包含一个tablestats表,该表将包含6列中每个表的信息。我将安排每天运行一个作业,计算前一天的时间戳、今天的行数和前一天行数之间的差值,然后将4列值合并为tablestats。
类似于:
| tablename | updyear | updmonth | updday | rowupdates | newrows |
|---|---|---|---|---|---|
| table_1 | 2023 | 2 | 5 | 2509 | 34 |
| table_1 | 2023 | 2 | 6 | 3443 | 90 |
| table_2 | 2023 | 2 | 5 | 834 | 255 |
| table_2 | 2023 | 2 | 6 | 544 | 433 |
有了它,我可以根据需要对数据进行趋势/透视。
我认为游标在一定程度上是最好的方法,因为我很难将查询的结果与所提取的表的名称进行浓缩。我改编了这个问题&;答案,以获得一部分的方式,类似于下面的代码,我缩写为易读性:
DECLARE @last_upd nvarchar(MAX) = '';
DECLARE @checkdate date = DATEADD(DAY, -1, GETDATE());
SELECT @last_upd = @last_upd + 'SELECT '''
+QUOTENAME(name)
+''',YEAR(last_upd) as updyear /* month, etc. */,COUNT(last_upd) as rowupdates FROM '
+ QUOTENAME(name)
+ ' WHERE last_upd > @checkdate /* GROUP BY year/month/day*/; '
FROM sys.tables
WHERE (name IN ('table_1','table_2','table_3'))
IF @@ROWCOUNT > 0
EXEC sp_executesql @last_upd
, N'@checkdate date'
, @checkdate'
返回以下内容:
| Query 1 | updyear | updmonth | updday | rowupdates |
|---|---|---|---|---|
| table_1 | 2023 | 2 | 5 | |
| table_1 | 2023 | 2 | 6 |
| Query 2 | updyear | updmonth | updday | rowupdates |
|---|---|---|---|---|
| table_2 | 2023 | 2 | 5 | |
| table_2 | 2023 | 2 | 6 |
查询3等。
虽然这只会每天运行,但MERGE语句将有助于解决与现有数据的任何潜在冲突。我还没有到进行行计数的地步,但假设最坏的情况是,在将行计数滚动到存储过程之前,我可以使用行计数进行第二次游标。