0

我有一个有 1000 多个表的数据库。这些表中有 100 个以三个字母为前缀(比如说“ABC”),这些表中只有一半具有 MODIFIEDDATETIME 列。

我正在尝试做一个简单的选择查询来获取每个表的所有最后更新的 MODIFIEDDATETIME 标记,该表实际上在该表上有一个 MODIFIEDDATETIME 并且也以三个字母前缀开头。

我试过使用这个功能,但它似乎没有让我到达那里。想法?

sp_msforeachtable '

select ''?'', modifieddatetime, count(*)
from ? 

where ? like ''%ABC%''
group by modifieddatetime
order by modifieddatetime desc
'
4

2 回答 2

6

借用今天早些时候的另一个答案

一方面,我建议远离无证和不受支持的程序,例如sp_MSForEachTable. 它们可以随时更改甚至从 SQL Server 中删除,并且此特定过程可能与许多针对sp_MSForEachDb. (在这里这里查看一些背景。)

...但也看到sp_ineachdb.

以下是我的做法 - 最重要的是,从元数据中提取行数 - 虽然不是 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;

也就是说,我不知道 usingMAX(MODIFIEDDATETIME)是否适合知道最后一次触摸桌子的时间。如果交易失败怎么办?如果最后一个操作是删除怎么办?

于 2012-04-23T14:40:50.573 回答
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
于 2012-04-23T14:29:36.307 回答