Tsql 当行依赖于外键值时,如何使用大容量插入?

Tsql 当行依赖于外键值时,如何使用大容量插入?,tsql,memory,foreign-keys,bulkinsert,Tsql,Memory,Foreign Keys,Bulkinsert,我的问题是关于 基于此,我考虑了使用。我现在明白了,我必须为我想要保存到数据库中的每个实体准备一个文件。不管怎样,我仍然想知道这个大容量插入是否会避免我的系统上的内存问题,如ServerFault上的参考问题所述 至于街道表,它很简单!作为外键,我只需要关心两个城市和五个部门。那么,地址呢?Addresses表的结构如下所示: AddressId int not null identity(1,1) primary key StreetNumber int null NumberSuffix_V

我的问题是关于

基于此,我考虑了使用。我现在明白了,我必须为我想要保存到数据库中的每个实体准备一个文件。不管怎样,我仍然想知道这个大容量插入是否会避免我的系统上的内存问题,如ServerFault上的参考问题所述

至于街道表,它很简单!作为外键,我只需要关心两个城市和五个部门。那么,地址呢?Addresses表的结构如下所示:

AddressId int not null identity(1,1) primary key
StreetNumber int null
NumberSuffix_Value int not null DEFAULT 0
StreetId int null references Streets (StreetId)
CityId int not null references Cities (CityId)
SectorId int null references Sectors (SectorId)
正如我在ServerFault上所说,我有大约35000个地址要插入。我要记住所有的身份证吗=P

然后,我现在要插入与地址有关联的公民

PersonId int not null indentity(1,1) primary key
Surname nvarchar not null
FirstName nvarchar not null
IsActive bit
AddressId int null references Addresses (AddressId)
我能想到的唯一一件事是强制ID为静态值,但随后,我失去了以前使用
INSERT..SELECT
stategy的方法所具有的灵活性

那么我的选择是什么

  • 我强制ID总是相同的,然后我必须
    设置IDENTITY\u INSERT ON
    ,这样我就可以将值强制到表中,这样我的每一行的ID总是相同的,就像建议的那样

  • 如何使用外键进行批量插入?我哪儿都找不到这方面的文件=(

  • 谢谢你的帮助

    编辑

    我编辑是为了包含最后为我编写的
    批量插入
    SQL指令

    我已经准备好了Excel工作簿,其中包含了需要插入的信息。因此,我只是创建了一些补充工作表,并开始编写公式,以便将信息数据“导入”到这些新工作表中。我的每个实体都有一个

  • 街道
  • 地址
  • 公民
  • 至于另外两个实体,不值得批量插入它们,因为我只有两个城市和五个区(城市分区)要插入。一旦插入了城市和区,我记下它们各自的ID,并开始准备批量插入的记录集。使用Excel的功能计算值并“导入”顺便说一句,外键本身就是一种魅力。之后,我将每个工作表保存到一个单独的CSV文件中。然后,我的记录就可以打包了

    USE [DatabaseName]
    GO
    
    delete from Citizens
    delete from Addresses
    delete from Streets
    
    BULK INSERT Streets
        FROM N'C:\SomeFolder\SomeSubfolder\Streets.csv'
        WITH (
            FIRSTROW = 2
            , KEEPIDENTITY
            , FIELDTERMINATOR = N','
            , ROWTERMINATOR = N'\n'
            , CODEPAGE = N'ACP'
        )
    GO
    
    • 第一排

      指示开始插入的行号。在我的情况下,我的CSV包含列标题,因此第二行是要开始的行。除此之外,可能需要从文件中的任何位置开始,比如说第15行

    • 基皮德实体

      允许大容量插入在文件实体id中指定的内容,即使该表具有标识列。当您希望使用精确id插入行时,此参数与在插入行之前设置标识\u插入我的表相同

    至于其他参数,它们自己说话

    既然已经解释了这一点,剩下的两个实体中的每一个都重复了相同的代码以插入地址和公民。而且由于指定了
    KEEPIDENTITY
    ,所以我的所有外键都保持不变,尽管我的主键在SQL Server中被设置为标识


    不过,只有几处调整,与marc_s在回答中所说的完全相同,只要尽可能快地将数据导入到一个无任何限制的暂存表中即可。这样,在遵循良好实践的同时,您的生活将变得更加轻松。=)基本思想是将数据批量插入到一个没有任何限制、任何约束等的暂存表中-只需尽快批量加载数据即可

    一旦在暂存表中有了数据,然后在将暂存表中的数据插入实际表时,您需要开始担心约束等问题

    在这里,你可以

    • 仅将符合所有条件的行插入到实际工作表中(并在临时表中将它们标记为“已成功插入”)

    • 处理保留在暂存表中的所有行,这些行没有通过某个错误/恢复过程成功插入—不管是什么:打印包含所有“问题”行的报告,将它们扔进“错误箱”或其他—完全由您决定


    关键点是:实际的
    批量插入
    应该放在一个完全不受约束的表中-只要尽可能快地加载数据-然后在第二步开始担心约束和查找数据和引用之类的事情

    我们的应用程序使用这种精确的策略一次加载数百万行。这很有意义,毕竟。插入数据行后,数据行始终更易于操作。谢谢你的支持,马克!=)我终于成功地批量插入了数千行!至于外键,有一个特殊参数
    KEEPIDENTITY
    ,因此可以在他的CSV文件中指定外键值,并期望插入这些外键值。