我有一个拥有1000多个表的数据库。其中100个表格以三个字母为前缀(比如'ABC')这些前缀表中只有一半有MODIFIEDDATETIME列。
我正在尝试执行一个简单的选择查询,以获取该表上实际具有MODIFIEDDATETIME的每个表的所有上次更新的MODIFIEDDATETIME标记,并且还以三个字母前缀开头。
我尝试过使用此功能,但它似乎没有让我在那里。想法?
sp_msforeachtable '
select ''?'', modifieddatetime, count(*)
from ?
where ? like ''%ABC%''
group by modifieddatetime
order by modifieddatetime desc
'
答案 0 :(得分:6)
借鉴another answer earlier today:
首先,我建议远离无证件和不受支持的人 像
sp_MSForEachTable
这样的程序。它们可以改变甚至改变 从任何时候都从SQL Server中删除,这个特定的过程可能会 许多人针对sp_MSForEachDb
报告的症状相同。 (看到 一些背景here和here,以及他们拥有的证据 无意修复,记录或支持here。)
以下是我将如何做到这一点 - 最重要的是,从元数据中提取行数 - 虽然不是100%准确到毫秒通常足够接近 - 不会让您的系统陷入执行每个表的扫描:
DECLARE @sql NVARCHAR(MAX);
SELECT @sql = N'';
CREATE TABLE #x
(
[table] NVARCHAR(255),
updated DATETIME,
[rowcount] BIGINT
);
SELECT @sql = @sql + N'INSERT #x SELECT '''
+ QUOTENAME(OBJECT_SCHEMA_NAME([object_id]))
+ '.' + QUOTENAME(OBJECT_NAME([object_id])) + ''',
MAX(MODIFIEDDATETIME), (SELECT SUM(rows) FROM sys.partitions
WHERE [object_id] = ' + CONVERT(VARCHAR(12), [object_id])
+ ') FROM ' + QUOTENAME(OBJECT_SCHEMA_NAME([object_id]))
+ '.' + QUOTENAME(OBJECT_NAME([object_id])) + ';'
FROM sys.columns
WHERE UPPER(name) = 'MODIFIEDDATETIME'
AND UPPER(OBJECT_NAME([object_id])) LIKE 'ABC%';
EXEC sp_executesql @sql;
SELECT [table],updated,[rowcount] FROM #x;
DROP TABLE #x;
那就是说,我不知道使用MAX(MODIFIEDDATETIME)
是否适合知道最后触摸一张桌子的时间。如果交易失败怎么办?如果最后一个操作是删除怎么办?
答案 1 :(得分:2)
你可以用动态SQL做到这一点,但这在1000个表上可能效率不高!
DECLARE @SQL NVARCHAR(MAX) = ''
SELECT @SQL = @SQL + ' UNION SELECT COUNT(' + QUOTENAME(Column_Name) + ') [Rows], MAX(' + QUOTENAME(Column_Name) + ') [MaxModifiedDate], ''' + QUOTENAME(Table_Schema) + '.' + QUOTENAME(Table_Name) + ''' [TableName] FROM ' + QUOTENAME(Table_Schema) + '.' + QUOTENAME(Table_Name)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE Column_Name = 'ModifiedDateTime'
AND Table_Name LIKE 'ABC%'
SET @SQL = 'SELECT MaxModifiedDate, TableName, Rows FROM (' + STUFF(@SQL, 1, 7, '') + ') t ORDER BY MaxModifiedDate DESC'
print @sql
EXEC SP_EXECUTESQL @SQL
它基本上构建了一个像
这样的查询SELECT MaxModifiedDate, TableName, Rows
FROM ( SELECT 'Table1' [TableName], MAX(ModifiedDate) [MaxModifedDate], COUNT(ModifiedDate) [Rows]
FROM Table1
UNION
SELECT 'Table2' [TableName], MAX(ModifiedDate) [MaxModifedDate], COUNT(ModifiedDate) [Rows]
FROM Table2
UNION
SELECT 'Table3' [TableName], MAX(ModifiedDate) [MaxModifedDate], COUNT(ModifiedDate) [Rows]
FROM Table3
UNION
...
) c
ORDER BY MaxModifiedDate DESC