【发布时间】:2011-12-05 03:09:31
【问题描述】:
我的问题与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 INSERTSQL 指令!
我已准备好 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 插入时,此参数与插入行之前的
SET INDENTITY_INSERT my_table ON相同。
至于其他参数,他们自己说话。
现在已经解释了这一点,为其余两个实体中的每一个重复相同的代码以插入地址和公民。而且因为指定了KEEPIDENTITY,所以我的所有外键都保持不变,尽管我的主键在 SQL Server 中设置为标识。
不过,只有一些调整,与marc_s 在他的回答中所说的完全相同,只需尽可能快地将数据导入暂存表,完全没有任何限制。这样,您将使您的生活更轻松,同时遵循良好的做法。 =)
【问题讨论】:
标签: tsql memory foreign-keys bulkinsert