sql-server - 如何查找受 SQL 影响的新记录集的表列表?
问题描述
我正在将数据从一个环境导出到另一个环境。我想选择插入或修改了新记录集的表列表。
数据库有大约 200 个表,并且只有自昨天以来有 10 个表记录受到影响,我只想过滤这些表。其中一些表没有createate表列。基于对表的普通选择查询很难识别记录差异。
如何查找受 SQL 影响的新记录集的表列表?如果可能的话,只有那些来自已识别表的新受影响的记录。
我试过这个查询,但是这个查询没有返回实际的表。
select * from sysobjects where id in (
select object_id
FROM sys.dm_db_index_usage_stats
WHERE last_user_update > getdate() - 1 )
解决方案
如果您没有时间戳或其他东西来识别新更改的记录,例如审计、利用触发器或在这些表上启用更改数据捕获,那么这是不可能做到的。
但是,阅读您的场景是不可能忽略已更改或修改的内容,而只是简单地将这 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 时,两个表必须具有完全相同的列数和类型。
我希望这会有所帮助。
推荐阅读
- msbuild - MSBuild,我怎样才能得到第二个父母
- python - gpg 上的非零 [错误] 代码:密钥服务器接收失败:无法分配请求的地址
- java - Spring Boot 测试 - 应该在 404 时返回 200
- css - 为什么网格行高太高?
- java - org.springframework.dao.InvalidDataAccessApiUsageException:实体不能为空
- r - 闪亮的 DTedit 问题:与 selectInput 和 Observe 事件结合时,添加新行将传递给连续的 data.frame。我怎样才能避免这种情况?
- flutter - 如何从名为 MyHomePage 的 StatefulWidget 中调用名为 MyDetailPage 的其他“ StatefulWidget ”或方法?
- material-ui - Material UI Drawer 永久变体不起作用。移出位置
- javascript - Javascript ArrayBuffer 到服务器端的文件
- flask - MathJax 在多行而不是内联渲染