Как найти список таблиц с новым набором записей в SQL? - PullRequest
0 голосов
/ 03 июля 2019

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

База данных насчитывает около 200 таблиц, и только если со вчерашнего дня пострадали 10 записей, я хочу отфильтровать только эти таблицы. В некоторых из этих таблиц нет созданного столбца таблицы. Труднее определить разницу записей на основе простого запроса на выборку в таблицу.

Как найти список таблиц с новым набором записей в SQL? И, если возможно, только те недавно затронутые записи из идентифицированных таблиц.

Я пытался с этим запросом, однако этот запрос не возвращает фактические таблицы.

select * from sysobjects where id in (
select object_id
FROM sys.dm_db_index_usage_stats
WHERE last_user_update > getdate() - 1 )

1 Ответ

1 голос
/ 03 июля 2019

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

Однако, читая ваш сценарий, нельзя ли игнорировать то, что изменилось или было изменено, и просто экспортировать эти 200 таблиц из одной среды в другую и переопределить его в месте назначения?

Если нет, то вас может заинтересовать только сравнение данных, а не идентификация вновь измененных записей, чтобы определить, какие таблицы не совпадают. Вы можете сделать это, используя EXCEPT

См. Ниже пример сравнения двух баз данных с одинаковыми именами таблиц и схемы, создающих столбец динамического оператора SQL с использованием EXCEPT из обеих баз данных на лету и запуска их в цикле while; вставка каждого имени таблицы, которая была обработана, во временную таблицу.

DECLARE @Counter AS INT
    ,   @Query AS NVARCHAR(MAX)

IF OBJECT_ID('tempdb..#CompareRecords') IS NOT NULL DROP TABLE #CompareRecords
IF OBJECT_ID('tempdb..#TablesNotMatched') IS NOT NULL DROP TABLE #TablesNotMatched
CREATE TABLE #TablesNotMatched (ObjectName NVARCHAR(200))

SELECT
        ROW_NUMBER() OVER( ORDER BY (SELECT 1)) AS RowNr
    ,   t.TABLE_CATALOG
    ,   t.TABLE_SCHEMA
    ,   t.TABLE_NAME
    ,   Query =     'IF' +  CHAR(13)
                +   '(' + CHAR(13)
                +   '   SELECT' + CHAR(13)
                +   '       COUNT(*) + 1' + CHAR(13)
                +   '   FROM' + CHAR(13)
                +   '   (' + CHAR(13)
                +   '       SELECT ' + QUOTENAME(t.TABLE_NAME, '''''') + ' AS TableName, * FROM ' + QUOTENAME(t.TABLE_CATALOG) + '.' + QUOTENAME(t.TABLE_SCHEMA) + '.' + QUOTENAME(t.TABLE_NAME) + CHAR(13)
                +   '       EXCEPT' + CHAR(13)
                +   '       SELECT ' + QUOTENAME(t.TABLE_NAME, '''''') + ' AS TableName, * FROM ' + QUOTENAME(t2.TABLE_CATALOG) + '.' + QUOTENAME(t.TABLE_SCHEMA) + '.' + QUOTENAME(t.TABLE_NAME) + CHAR(13)
                +   '   ) AS sq' + CHAR(13)
                +   ') > 1' + CHAR(13)
                +   'SELECT ' + QUOTENAME(QUOTENAME(t.TABLE_CATALOG) + '.' + QUOTENAME(t.TABLE_SCHEMA) + '.' + QUOTENAME(t.TABLE_NAME), '''''') + ' AS TableNameRecordsNotMatched'
    INTO #CompareRecords
FROM <UAT_DATABASE>.INFORMATION_SCHEMA.TABLES AS t
LEFT JOIN <PROD_DATABASE>.INFORMATION_SCHEMA.TABLES AS t2 ON    t.TABLE_SCHEMA = t2.TABLE_SCHEMA 
                                                            AND t.TABLE_NAME = t2.TABLE_NAME

WHERE t.TABLE_TYPE = 'BASE TABLE'


SET @Counter = (SELECT MAX(RowNr) FROM #CompareRecords)

WHILE @Counter > 0
    BEGIN
        SET @Query = (SELECT cr.Query FROM #CompareRecords AS cr WHERE cr.RowNr = @Counter)
        INSERT INTO #TablesNotMatched
        EXECUTE sp_executesql @Query
        SET @Counter = @Counter - 1
    END

SELECT
        *
FROM #TablesNotMatched

Обратите внимание, что при использовании ИСКЛЮЧИТЬ обе таблицы должны иметь одинаковое количество столбцов и тип.

Надеюсь, это немного поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...