【问题标题】:Transform and copy table data转换和复制表数据
【发布时间】:2015-04-24 15:29:53
【问题描述】:

抱歉,如果之前有人问过这个问题,但我正在发布它,因为无法在论坛中找到任何相关内容。所以任何帮助将不胜感激。 这是我的场景。

我们有一个 SQL 表视图 A(只读访问),其中包含位于域 A 的服务器 A 上的一组数据。 我们有我们的 SQL 数据库,其中表 B 位于域 B 的服务器 B 上。 我们已经在 2 个域之间打开了端口。

我们需要编写一个 SSIS 作业(每天运行),它将从视图 A 中获取数据并插入到表 B 中。那么实现此目的的最佳方法是什么。

注意:

  • 服务器上的表视图没有删除或上次修改的列 所以无法弄清楚有什么变化。 (如果有其他方法请告诉我)
  • 数据库数据大约有 50k 条记录

方法一:

  • 从视图中导出数据
  • 转换它
  • 在服务器 B 上删除表
  • 插入转换后的数据

方法二:

  • 从视图中导出数据
  • 转换它
  • 插入临时表
  • 在日志表中创建一个日志条目
  • 当日志条目显示成功复制时,触发删除所有行并将数据从临时表复制到表 B。
  • 如果出现问题,请回滚。

【问题讨论】:

    标签: sql ssis sql-server-2008-r2


    【解决方案1】:

    我推荐第三种方法在服务器 B 上的数据库 B 中应用新的暂存表和历史表。暂存表将主要反映您的表 B,但不包含任何约束,并且将有一个额外的位列定义状态。历史表将主要反映表 B 结构,但将包含两个附加列(ChangeDate 和 ChangeMade)。最后,对于这种方法,您需要确定用于将视图中的记录定义为唯一的列。

    • 截断暂存表(根据之前的结果)。
    • 将数据从视图(服务器 A)导出到临时表(服务器 B)。
    • 运行 SQL 任务以检查每条记录的一致性和质量。通过的记录,将状态位字段值设置为 1,否则设置为 0。
    • 在 SQL 任务中应用 MERGE 调用以将数据从源(暂存表)转换到目标表(表 B)并更新历史表。这仅适用于那些状态 = 1 的记录。使用 MERGE,您还可以将更改的历史记录输出到新的历史记录表中,指示“I”表示插入,“U”表示更新或“D”表示删除基于 MERGE 中定义的匹配。
    • 对于 Staging 表中值为 0 的记录,向需要知道已找到 X 条问题记录的人发送电子邮件。

    这里的想法是,该过程不会停止,如果发现一条错误记录,您无需强制回滚。此外,您可以通过查看暂存表来监控日常流程。我过去采用了这种方法,并将其集成到发送电子邮件警报中,其中包含指向报告问题记录的 SSRS 报告的链接。这样做让我能够主动在问题记录中找到模式,并与我上游的人一起解决问题。如果您有超过一百万条记录被视图拉取,那么您可能希望向 Staging 表添加一个代理键(设置为主),其标识从 1 开始,并且随着导入的每条新记录自动递增 1从视图。在运行 MERGE 之前,使用代理键设置聚集索引。这将大大提高 MERGE 的性能。就在第一步截断临时表之前,删除索引。

    希望这会有所帮助。

    【讨论】:

    • 感谢您的回复,我喜欢您的想法,但您能否解释一下关于截断、关于 sql 任务的更多信息。
    • SSIS 包中的第一步或任务是截断暂存表(从表中删除所有记录并重置任何身份)。然后使用视图中的当前记录重新填充暂存表。这一切都可以在存储过程中轻松完成,而不是使用 SSIS 包。使用 MERGE 应用暂存表和历史表为您提供了识别不良记录和跟踪历史更改的方法。
    • 以下链接很好地描述了暂存表:Staging table link
    • 以下链接很好地描述了 MERGE 语句:[MERGE link] (purplefrogsystems.com/blog/2011/12/…)
    • 最后,以下链接显示了如何应用带有 OUTPUT 子句的 MERGE,以便在插入、更新和删除记录时将信息发送到历史记录表:MERGE with OUTPUT link
    【解决方案2】:

    只需创建一个包含三个语句的 SQL 存储过程即可实现 - insert -- 用于将新记录从 A 插入到 B -更新 - 更新之前复制的记录中发生的更改,因为作业将每天运行 -delete -- 如果 A 中删除了任何记录,则删除 B 中的所有已删除记录

    如果您需要对此解决方案的任何说明,我会很高兴

    【讨论】:

    • 感谢您的回复,但是您如何跟踪记录是否已更新删除,请注意我在原始视图中没有任何标记
    • 您只需要 (1) 在更新中在 A 和 B 之间进行内部连接,以便获得公共记录然后更新例如
    • --(2) 在插入中,您在 A 和 B 之间进行左连接,其中 A 是左侧,B 是右侧,并且您在 B 中的 ID 为 null 的位置插入,这意味着您插入仅新记录。例如:(插入 B(col1,col2,etc) select (A.col1,A.col2,etc) from A left outer join B.ID on A.id = b.id where B is null ---
    • (3)在删除中,您还将在 B 和 A 之间创建一个左外连接语句,但这次 B 是左侧并检查 A.id 为空的记录,这意味着那些记录存在但已删除,例如 [delete from B left outer join A on A.id =B.id where A.id is null 。如果您需要更多说明,我会很高兴
    猜你喜欢
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多