0

1000以上のテーブルを持つDBがあります。これらのテーブルの 100 には、3 文字のプレフィックスが付けられています (「ABC」としましょう)。これらのプレフィックス付きのテーブルの半分だけが MODIFIEDDATETIME 列を持っています。

私は単純な選択クエリを実行して、実際にそのテーブルに MODIFIEDDATETIME があり、3 文字のプレフィックスで始まる各テーブルの最後に更新された MODIFIEDDATETIME スタンプをすべて取得しようとしています。

この関数を使用してみましたが、うまくいかないようです。考え?

sp_msforeachtable '

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

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

2 に答える 2

6

今日の早い段階で別の回答から借りる:

1 つには、ドキュメント化されておらず、サポートされていない手順には近づかないことをお勧めします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;

MAX(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 に答える