我的问题与this one I asked on ServerFault有关。
基于此,我考虑过使用BULK INSERT
。我现在明白,我必须为每个要保存到数据库中的实体准备一个文件。无论如何,我仍然想知道这个BULK INSERT是否会避免我的系统上的内存问题,如ServerFault上引用的问题所述。
至于Streets表,它很简单!我只有两个城市和五个部门需要关心作为外键。但那么,地址怎么样? 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上所说,我有大约35,000个要插入的地址。我要记住所有的ID吗? = 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
状态的方法所带来的灵活性。
那么我的选择是什么?
我强制ID始终相同,然后我必须SET IDENTITY_INSERT ON
以便我可以强制将值放入表中,这样我的每个行总是有相同的ID正如建议here。
如何使用外键进行BULK INSERT?我无法在任何地方获得任何文档。 =(
感谢您的帮助!
修改
我进行了编辑,以便包含最终为我制作的
BULK INSERT
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
FIRSTROW
表示开始插入的行号。在我的情况下,我的CSV包含列标题,因此第二行是开头的那一行。除此之外,人们可能想要从他的档案中的任何地方开始,比方说第15行。
KEEPIDENTITY
即使表具有标识列,也允许批量插入指定的文件内实体ID。当您希望插入精确ID时,此参数与插入行之前的
SET INDENTITY_INSERT my_table ON
相同。
至于其他参数,他们自己说话。
现在解释了这一点,为剩下的两个实体中的每一个重复相同的代码以插入地址和公民。并且因为指定了KEEPIDENTITY
,所以我的所有外键都保持不变,尽管我的主键在SQL Server中设置为标识。
虽然只有一些调整,就像marc_s
在答案中所说的那样,只需尽可能快地将数据导入到一个没有任何限制的临时表中。通过这种方式,你可以让你的生活更轻松,同时遵循良好的做法。 =)
答案 0 :(得分:16)
基本思路是将您的数据批量插入暂存表,该表没有任何限制,任何约束等。 - 只需尽可能快地批量加载数据。
在登台表中有数据后,然后,当您将登台表中的数据插入真实表格时,您需要开始担心约束等。
在这里,你可以这样。
仅将这些行插入符合所有条件的实际工作表中(并在临时表中将其标记为“已成功插入”)
处理临时表中未被某些错误/恢复过程成功插入的所有行 - 无论是什么:打印包含所有“问题”行的报告,将它们扔进“错误bin“或其他 - 完全取决于你。
关键点是:实际的BULK INSERT
应该进入一个完全无约束的表 - 只需尽可能快地加载数据 - 然后在第二步开始担心约束和查找数据和引用这样的东西