【问题标题】:Azure Data Factory Copy Identity Column With Gaps带有间隙的 Azure 数据工厂复制标识列
【发布时间】:2017-02-06 21:55:45
【问题描述】:

我创建了一个管道和两个链接服务来将数据从 SQL Server 的本地实例移动到 Azure Sql 实例。我遇到的问题是我们在本地有一个表“Table-1”,其中一个 Identity (1,1) 列缺少顺序 ID(例如,值是 1、2、3、4 , 6)。当管道运行时,它会尝试插入 ID 为 1、2、3、4、5 的行,这是一个大问题,因为 ID 6 是另一个表“Table-2”上的外键,现在它不存在,因此将数据移动到表 2 失败并出现 SQL 错误 547(插入语句与外键约束冲突...)。

在我看来,正确的做法是使该列不是身份,但这不是我现在的选择,因为创建记录的应用程序代码希望该列是自动生成的。

除了不使用数据工厂之外,还有其他方法吗?我希望看到它自动为带有 Identity 列的表打开和关闭 identity_insert,虽然我知道这会强制这些表一次处理一个,但该选项会很好,并且不会破坏我的关系。

编辑:根据 wBob 的建议,我还在此处添加了一个功能请求(如果您愿意对其进行投票):https://feedback.azure.com/forums/270578-data-factory/suggestions/17996950-add-support-for-maintaining-identity-column-values

【问题讨论】:

  • 我想我可以为每个表编写一个脚本,将表数据作为管道定义的一部分,用于那些具有标识列的表...

标签: sql-server azure-sql-database azure-data-factory


【解决方案1】:

Azure 数据工厂本身不支持打开或关闭表的标识属性,但我想到了两种解决方法。

  1. 使用数据工厂将数据加载到临时表中(其中未设置身份属性),然后使用Stored Proc 任务调用存储过程,您可以在其中进行更严格的控制,包括将身份属性设置为或关闭。
  2. 如果您使用的是 Azure SQL 数据库(或 VM 上的 SQL Server),则可以使用表值参数并将数据传递到存储的 proc 任务中,从而跳过暂存表。此技术不适用于 Azure SQL 数据仓库。对于大容量,我可能不会推荐这个。这个example 展示了如何:

https://github.com/Microsoft/azure-docs/blob/master/includes/data-factory-sql-invoke-stored-procedure.md

我无法测试这些,但相信它们会起作用。如果您有任何问题,请告诉我。

【讨论】:

  • 你采用了哪种方法?
【解决方案2】:

我接受了 wBob 的回答,但想更详细地说明我所做的事情。

我可能有 100 个表要移动,其中包含各种依赖项和身份。下面是我将数据转换为 azure 所执行的步骤:

  1. 创建一个管道来移动通过查询 sys.tables 找到的所有没有身份和依赖关系的表:

    select *
    from sys.tables t
    where not exists (
        select *
        from sys.columns c 
        where c.object_id = t.object_id
        and is_identity = 1
    )
    

    并将此处的结果与 oType = 8 的 sp_msdependencies 的结果进行对比。然后,我获取了此结果集中 oSequence = 1(无依赖关系)的所有表,并将这些表放入管道中并运行它。

  2. 我创建了一个暂存模式并重新创建了所有带有标识列的表(通过删除 (1.) 中查询中的“not”找到,其中有 60 多个)并删除创建它们时的身份规范。

  3. 然后我创建了另一个数据工厂管道来将数据移动到这些暂存表中。

  4. 运行一堆“插入...”语句以将数据从暂存表移动到其载有身份的对应表中,每次都将 identity_insert 设置为打开和关闭。注意:在这里,我还必须注意 sp_msdependencies 结果,以免出现外部错误

  5. 创建了一个数据工厂管道来移动剩余的表。

呼……

【讨论】:

  • 感谢您的更新。听起来您的一天很忙 :) 考虑提出反馈请求 here 以获得数据工厂中的身份支持。
  • 谢谢 wBob,刚刚添加了这个想法
【解决方案3】:

今天遇到了这个问题,有 2500 万行数据集,所以真的很想进行 Ident Insert 而不是通过另一个表暂存。

在复制数据(接收器/预复制脚本)步骤只需添加: 设置 identity_insert [schema].[table] on

在以下之后立即添加查找: 设置 identity_insert [schema].[table] 关闭 选择 1 作为结果集

您需要结果,因为它是一个查找并且不要忘记,您一次只能运行这些步骤中的一个,因为 Ident insert 一次只能在一个表上,除非有人告诉我这样做了使用 SQL 2005 :-)

【讨论】:

  • 这仅适用于 BULK IMPORT,不适用于 polybase...
猜你喜欢
  • 1970-01-01
  • 2019-11-19
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多