Как получить список таблиц, которые не были обновлены в определенном диапазоне дат? - PullRequest
0 голосов
/ 08 ноября 2018

Я использую Alteryx для передачи данных на наш SQL Server, а затем использую SSMS для просмотра таблиц. У меня более 100 таблиц, и в настоящее время я просматриваю каждую таблицу и делаю select top 1000 rows, чтобы увидеть столбец SysUpdatedOn, который является отметкой даты, чтобы подтвердить, что моя таблица была обновлена. Есть ли запрос, который будет проходить через каждую таблицу, искать отметку времени, предшествующую определенной дате, и давать мне список этих таблиц? Я ищу, чтобы получить список таблиц, которые не были обновлены во время нашего процесса обновления данных.

Я нашел этот запрос, и он будет искать определенную строку во всех таблицах, однако я не могу добавить что-то подобное в приведенный ниже запрос.

DECLARE @SearchStr NVARCHAR(100) <= 11/6/2018

USE DATABASE_NAME

DECLARE @SearchStr NVARCHAR(100) = 'SEARCH_TEXT'
DECLARE @Results TABLE (ColumnName NVARCHAR(370), ColumnValue NVARCHAR(3630))

SET NOCOUNT ON

DECLARE @TableName NVARCHAR(256), 
        @ColumnName NVARCHAR(128), 
        @SearchStr2 NVARCHAR(110)

SET  @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')

WHILE @TableName IS NOT NULL
BEGIN
    SET @ColumnName = ''
    SET @TableName = 
    (
        SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
        FROM INFORMATION_SCHEMA.TABLES
        WHERE TABLE_TYPE = 'BASE TABLE'
          AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
          AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + 
                                       QUOTENAME(TABLE_NAME)), 'IsMSShipped') = 0
    )

    WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
    BEGIN
        SET @ColumnName =
        (
            SELECT MIN(QUOTENAME(COLUMN_NAME))
            FROM INFORMATION_SCHEMA.COLUMNS
            WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
              AND TABLE_NAME = PARSENAME(@TableName, 1)
              AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'int', 'decimal')
              AND QUOTENAME(COLUMN_NAME) > @ColumnName
        )

        IF @ColumnName IS NOT NULL
        BEGIN
            INSERT INTO @Results
            EXEC
            (
                'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + 
@ColumnName + ', 3630) 
                FROM ' + @TableName + ' (NOLOCK) ' +
                ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
            )
        END
    END    
END

SELECT ColumnName, ColumnValue FROM @Results

Любая помощь будет принята с благодарностью!

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Вы можете использовать столбец LAST_USER_UPDATE в SYS.DM_DB_INDEX_USAGE_STATS, чтобы проверить последний раз, когда данные были вставлены или обновлены.Если вам нужно отслеживать изменения DDL, используйте столбец MODIFY_DATE в SYS.OBJECTS, но, поскольку вы ищете изменения во время обновления, я предполагаю, что вы хотите отслеживать DML.Фильтр GETDATE / DATEADD является лишь примером, вы можете заменить его датой, к которой нужно фильтровать.

SELECT O.NAME AS TABLENAME 
FROM SYS.OBJECTS O
INNER JOIN SYS.DM_DB_INDEX_USAGE_STATS I ON O.OBJECT_ID = I.OBJECT_ID
--FOR USER TABLES
WHERE O.TYPE = 'U' AND I.LAST_USER_UPDATE < DATEADD(DAY, -1, GETDATE())
0 голосов
/ 08 ноября 2018

Что-то, что я только что обнаружил, исследуя ваш запрос (это может быть довольно круто и расширенно, и я могу начать его использовать), если вы точно знаете, что столбец существует в каждой таблице в БД, это может сработать, он выполняется для каждой таблицы в БД: https://weblogs.sqlteam.com/joew/archive/2007/10/23/60383.aspx

DECLARE @Table AS TABLE (TableName VARCHAR(5000), CountRows INT)

INSERT INTO @Table        
EXEC sp_MSforeachtable @command1 = 'select ''?'', count(*) from ? WITH (NOLOCK) WHERE SysUpdatedOn >= ''11/6/2018'' '

SELECT * FROM @Table
...