批量插入自引用表

时间:2019-03-07 17:43:54

标签: c# .net sql-server sql-server-2017

这个问题是a much more complex problem的一部分,出于我的理智,我将其细分为几个小块。

假设我有一个Parts表,该表是自引用的,看起来像这样:

PartId  ParentPartId  Description             PartNumber   IsCatHeader     ProviderId
---------------------------------------------------------------------------------------
9292       null       'Engine Parts'           null           1      'Engine Parts||1'
9293       9292       'Engine Bolts'           null           1      'Engine Bolts||1'
9294       9293       '6mm Engine Bolt'        'X1-234-ABC'     0      '6mm Engine Bolt|X1-234-ABC|0'
9295       9293       '5mm Engine Bolt'        'X2-934-BCD'     0      '5mm Engine Bolt|X2-934-BCD|0'
9296       9295       '5mm Engine Bolt Washer' 'X2-934-GED'     0      '5mm Engine Bolt Washer|X2-934-GED|0'

您明白了。现在,我们正在导入这些部分的整本书(大量CSV文件),从而在一本书中导入了数百个订单项。

部分经常在书籍之间重复,我们的工作之一是将重复项保留在数据库之外。

源不为这些部分提供任何类型的唯一ID,因此我们创建了一个ProviderId列,该列是来自创建唯一字符串的每个记录的数据部分的集合。然后,我们可以在导入时使用它来检查重复项。 (此列中的实际数据比我在这里显示的要复杂。)

所以,现在到我的问题了。我正在尝试找出批量执行此操作的最佳方法。一种选择(不好的选择)是从C#应用程序一次循环浏览每个项目。...插入父项,获取范围标识,插入所有子项,等等。在大书中,这将导致每本书成千上万的数据库调用。没有选择。

我们需要批量插入解决方案。但是我们对此的自引用方面确实有一个难题。

我们最初的想法是在C#中建立ENTIRE数据模型,包括所有PartIdParentPartId的数据模型。然后,将其直接直接插入Parts表中。但是,与此有关的问题是知道以什么ID开头。请记住,多个进程将同时运行,并且许多部分将重复。我们尝试使用SEQUENCE对象,但这带来了问题……如果重复的书有100%的可能被处理,如果使用SEQUENCE,这将导致ID的巨大缺口。

我现在要追求的课程是...我们创建了一个Parts_Staging表,该表看起来几乎与实际的Parts表相似。我们可以对其进行批量插入,没问题。然后,使用ProviderId列在Parts_Staging中查找Parts中不存在的记录并将它们移到一个简单的查询。

但是,通过这种方式,我没有足够的创造力(或经验),无法想象一种方法来进行此移动/合并并保持自引用id不变。

我一直在阅读“ How to Insert data into self reference table in sql server?”和“ T-SQL - Insert Data into Parent and Child Tables”之类的主题,但到目前为止,我仍然没有看到这个愿景。

1 个答案:

答案 0 :(得分:3)

好的。这就是我要做的。首先,用C#组成集合中的序列及其父子关系。但是我将其放在不同的列中,也许像BatchPartIdBatchParentPartId之类。 (也许是一个不同的关联表。没关系。)

| PartId | ParentPartId | BatchPartId | BatchParentPartId |
|--------|--------------|-------------|-------------------|
|        |              | XX1901      |                   |
|        |              | XX1902      | XX1901            |
|        |              | XX1903      | XX1901            |
|        |              | XX1904      | XX1903            |
|        |              | XX1905      | XX1903            |

然后,插入整个列表,以创建PartId

| PartId | ParentPartId | BatchPartId | BatchParentPartId |
|--------|--------------|-------------|-------------------|
| 55     |              | XX1901      |                   |
| 56     |              | XX1902      | XX1901            |
| 57     |              | XX1903      | XX1901            |
| 58     |              | XX1904      | XX1903            |
| 59     |              | XX1905      | XX1903            |

在发布后,您可以在此处用行的ParentPartId填充PartId,并在子行的BatchPartId中填充相应的BatchParentPartId

| PartId | ParentPartId | BatchPartId | BatchParentPartId |
|--------|--------------|-------------|-------------------|
| 55     |              | XX1901      |                   |
| 56     | 55           | XX1902      | XX1901            |
| 57     | 55           | XX1903      | XX1901            |
| 58     | 57           | XX1904      | XX1903            |
| 59     | 57           | XX1905      | XX1903            |