我正在将数据从一个环境导出到另一个环境。我想选择具有已插入或已修改的新记录集的表的列表。
数据库大约有200张表,并且仅自昨天以来10条表记录受到影响,我只想过滤那些表。其中一些表没有 createdate 表列。难以基于对表的普通选择查询来确定记录差异。
如何查找对SQL有新记录集的表的列表? 并且,如果可能的话,仅使用已识别表中的那些新受影响的记录。
我尝试使用此查询,但是此查询未返回实际表。
select * from sysobjects where id in (
select object_id
FROM sys.dm_db_index_usage_stats
WHERE last_user_update > getdate() - 1 )
答案 0 :(得分:1)
如果您没有时间戳或标识新更改的记录的内容(例如审核,利用触发器或在这些表上启用了Change Data Capture),那么就无法做到。
但是,阅读您的方案后,是否无法忽略已更改或修改的内容,而只是将那200个表从一个环境导出到另一个环境并在目标位置覆盖它?
如果不是,那么您可能只对比较数据感兴趣,而不是识别新更改的记录以识别哪些表不匹配。您可以使用EXCEPT
请参见下面的示例,该示例将两个具有相同表名和模式的数据库进行比较,并使用EXCEPT快速创建两个SQL数据库,并在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
请注意,使用EXCEPT时,两个表的列数和类型必须完全相同。
我希望这会有所帮助。