【问题标题】:How to compare rows in source and destination tables dynamically in SQL Server如何在 SQL Server 中动态比较源表和目标表中的行
【发布时间】:2012-04-10 19:15:16
【问题描述】:

我们收到来自客户的数据馈送,并且每次都获得大致相同的架构,尽管在客户端使用 3 方应用程序时它可能会发生变化。当我们收到数据文件时,我们将数据导入一个暂存数据库,其中每个数据文件(学生、出勤等)都有一个表格。然后,我们希望将该数据与我们已经存在于该客户数据库中的数据进行比较,并查看上次运行中哪些数据已更改(列已更改或整行可能已删除)。然后,我们希望将更新的值或删除的行写入审计表,这样我们就可以返回查看从之前的数据导入中更改了哪些数据。我们不想更新数据本身,我们只想记录两个数据集之间的不同之处。然后,我们将从客户数据库中删除所有数据,并从新数据文件中完全导入数据而不更改(此指令已下达,无法更改)。最大的问题是我需要动态地执行此操作,因为我不确切知道我将从我们的客户那里获得什么模式,因为他们可以对他们的表进行自定义。我需要能够动态确定目标中有哪些表及其结构,然后查看源并比较值以查看数据中发生了什么变化。

附加信息: 源中没有 ID 列,但有几列可用作构成不同行的代理键。

我希望能够为每个表通用地执行此操作,而不必在其中硬编码值,尽管我可能必须为单独的引用表中的每个表的代理键执行此操作。

我可以使用 SSIS、SP、触发器等,无论哪个更有意义。我已经查看了所有内容,包括 tablediff,但似乎没有一个拥有我需要的一切,或者一旦我进入它们,逻辑就会变得非常复杂。

当然,任何人已经做过类似的事情的任何具体例子都将不胜感激。

如果还有其他有用的信息,请告诉我。

谢谢

【问题讨论】:

  • 请包括表/文件结构。
  • @Maess - 你读过这个问题吗?表格发生变化。
  • 您的所有客户都向您发送文件。您获得的这些文件有一组通用的列,但客户可以添加自己的自定义列。您是否关心这些自定义列中的数据?因为您正在谈论动态更新每个文件的永久表架构,假设您想要保留自定义数据。
  • 我们可能会在未来的某个时间关心数据,但我们不一定知道我们得到数据时的数据是什么。是的,我每次获得新数据时都会更新架构,因此我会保留他们发送给我的任何新数据点。

标签: sql sql-server tsql ssis


【解决方案1】:

我曾研究过类似的问题,并使用了一系列元数据表来动态比较数据集。这些元数据表描述了需要暂存哪些数据集以及哪些列组合(及其数据类型)用作每个表的业务键。

通过这种方式,您可以动态构造一个 SQL 查询(例如,使用 SSIS 脚本组件),该查询执行完全外连接以找出两者之间的差异。

您可以将自己的元数据与 SQL Server 的元数据连接起来(使用 sys.* 或 INFORMATION_SCHEMA.*),以检测源中是否仍然存在列以及数据类型是否与您预期的一样。

将不匹配的元数据重定向到错误流进行评估。

这种工作方式风险很大,但如果你维护好你的元数据是可以做到的。

【讨论】:

  • 我最终使用 information_schema 获取表的列列表,然后为我的 EXCEPT 比较构建列列表,如下所示。这给了我一个小得多的数据集来使用和游标来确定数据是更新还是删除。与我之前看到的几百万行相比,使用几百行/几千行要好得多。
【解决方案2】:

如果你想比较两个表来看看有什么不同,关键字是'except'


select col1,col2,... from table1
except
select col1,col2,... from table2

这将为您提供 table1 中的所有内容,而不是 table2。


select col1,col2,... from table2
except
select col1,col2,... from table1

这将为您提供 table2 中不在 table1 中的所有内容。


假设您在两个表上都有某种有用的持久主键,那么这两个集合中的所有内容都会发生变化。第一组中的所有内容都是插入;第二组中的所有内容都是删除。

【讨论】:

  • 这实际上是我用来缩小需要检查以查看它们是否已更改的记录的方法。没有 PK,但有几列我们定义为数据集的“键”。我们最终在一个单独的表中列出了这些列。然后我使用 except 比较完整的行,以获取两个数据集中不同的行(使用 INFORMATION_SCHEMA),然后比较两者之间的“关键”列。如果键相同,那么我只是将其计为更改的行,并使用每列的旧/新值记录更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多