批量插入 SQL 服务器
Bulk Inserts SQL Server
我很好奇是否有人可以建议一种更好的批量插入方法。在我目前的工作中,我们正在构建 xml 字符串,这些字符串作为变量传递给存储过程,然后创建临时 table 并插入 xml。很多时候我看到正在使用的光标,如果可能的话我不想这样做
DECLARE @DriverToImport TABLE
(DriverId INT NULL DEFAULT (0),
IsNew TINYINT NOT NULL DEFAULT (0),
DriverExternalId NVARCHAR(20) NOT NULL,
DriverName NVARCHAR(100) NOT NULL,
HireDate SMALLDATETIME NULL,
HomeNumber NVARCHAR(20) NULL,
CellNumber NVARCHAR(20) NULL,
DriverTypeId INT NOT NULL,
ISDId INT NOT NULL,
CreatedBy NVARCHAR(50) NOT NULL,
DtCreated SMALLDATETIME NOT NULL,
LastUpdatedBy NVARCHAR(50) NOT NULL,
DtLastUpdated SMALLDATETIME NOT NULL,
PINCode NVARCHAR(20) NULL,
UNIQUE (DriverExternalId)
)
INSERT INTO @DriverToImport (DriverExternalId, DriverName, HireDate, HomeNumber, CellNumber, DriverTypeId, ISDId, CreatedBy, DtCreated, LastUpdatedBy, DtLastUpdated, PINCode)
SELECT
T.c.value('./Id[1]', 'NVARCHAR(20)'),
T.c.value('./Fn[1]', 'NVARCHAR(50)') + ', ' + T.c.value('./Ln[1]', 'NVARCHAR(50)') + ' ' + T.c.value('./Mn[1]', 'NVARCHAR(50)'),
T.c.value('./HireDate[1]', 'SMALLDATETIME'),
T.c.value('./HomeNumber[1]', 'NVARCHAR(20)'),
T.c.value('./CellNumber[1]', 'NVARCHAR(20)'),
(SELECT dt.DriverTypeId
FROM DriverType dt
WHERE dt.DriverTypeName LIKE '%' + T.c.value('./DriverType[1]', 'NVARCHAR(20)') + '%'),
@ISDId, @UserName, @dtCurrent, @UserName, @dtCurrent,
T.c.value('./PinCode[1]', 'NVARCHAR(20)')
FROM
@xmlDoc.nodes('/Drivers/Driver') T (c)
WHERE
(T.c.value('./Id[1]', 'NVARCHAR(20)') IS NOT NULL)
AND (T.c.value('./Id[1]', 'NVARCHAR(20)') <> '')
DECLARE newDriverCursor CURSOR FAST_FORWARD FOR
SELECT
t.DriverExternalId, t.DriverName, t.HireDate,
t.HomeNumber, t.CellNumber, t.DriverTypeId,
t.CreatedBy, t.DtCreated, t.LastUpdatedBy, t.DtLastUpdated,
t.PINCode
FROM
@DriverToImport t
WHERE
(t.IsNew = 1)
OPEN newDriverCursor
FETCH NEXT FROM newDriverCursor INTO @DriverId, @DriverName, @HireDate, @HomeNumber, @CellNumber, @DriverTypeId, @CreatedBy, @DtCreated, @LastUpdatedBy, @DtLastUpdated, @PINCode
WHILE (@@fetch_status = 0)
BEGIN
INSERT INTO dbo.Driver (DriverExternalId, DriverName, EmployeeNumber, HireDate, HomeNumber, CellNumber, DriverTypeId, ISDId, CreatedBy, DtCreated, LastUpdatedBy, DtLastUpdated, PINCode, IsActive, ResetPIN)
VALUES (@DriverExternalId, @DriverName, @DriverExternalId, @HireDate, @HomeNumber, @CellNumber, @DriverTypeId, @ISDId, @CreatedBy, @DtCreated, @LastUpdatedBy, @DtLastUpdated, @PINCode, 1, 0)
END
我知道过去我使用带有 SQL 变量的合并语句来进行批量插入。这也很好用,但需要为每个变量创建一个 table 变量。所以我的问题是 SQL Server 2016 是否有更强大的方法来处理批量插入?
术语 "bulk insert" 相当含糊,所以这取决于您的意思。根据您的描述,听起来您可能想查看 SQL Server side and from the .Net Framework side 中的 Table Valued Parameters。将 XML 字符串或定界字符串直接传递给存储过程并在存储过程中进行 XML 分解的旧方法本质上是 TVP 旨在取代的方法。从概念上讲,它的作用是允许您将 .Net DataTable 作为参数提交给存储过程 whole-hog。
不过,我也能想到bulk insert的其他含义。有 SqlBulkCopy class, which allows you to insert a DataTable as a single step fairly efficiently. There's also the BULK INSERT SQL statement,主要用于加载 CSV 文件。此外,还有 SSIS,它是一个完整的 ETL 包。如果您需要的逻辑比 BULK INSERT 允许的更多,或者需要进行额外的映射,有些人已经使用 SSIS 在系统之间完成了。
所以,就像我说的,这在某种程度上取决于 "bulk insert" 的意思。
我很好奇是否有人可以建议一种更好的批量插入方法。在我目前的工作中,我们正在构建 xml 字符串,这些字符串作为变量传递给存储过程,然后创建临时 table 并插入 xml。很多时候我看到正在使用的光标,如果可能的话我不想这样做
DECLARE @DriverToImport TABLE
(DriverId INT NULL DEFAULT (0),
IsNew TINYINT NOT NULL DEFAULT (0),
DriverExternalId NVARCHAR(20) NOT NULL,
DriverName NVARCHAR(100) NOT NULL,
HireDate SMALLDATETIME NULL,
HomeNumber NVARCHAR(20) NULL,
CellNumber NVARCHAR(20) NULL,
DriverTypeId INT NOT NULL,
ISDId INT NOT NULL,
CreatedBy NVARCHAR(50) NOT NULL,
DtCreated SMALLDATETIME NOT NULL,
LastUpdatedBy NVARCHAR(50) NOT NULL,
DtLastUpdated SMALLDATETIME NOT NULL,
PINCode NVARCHAR(20) NULL,
UNIQUE (DriverExternalId)
)
INSERT INTO @DriverToImport (DriverExternalId, DriverName, HireDate, HomeNumber, CellNumber, DriverTypeId, ISDId, CreatedBy, DtCreated, LastUpdatedBy, DtLastUpdated, PINCode)
SELECT
T.c.value('./Id[1]', 'NVARCHAR(20)'),
T.c.value('./Fn[1]', 'NVARCHAR(50)') + ', ' + T.c.value('./Ln[1]', 'NVARCHAR(50)') + ' ' + T.c.value('./Mn[1]', 'NVARCHAR(50)'),
T.c.value('./HireDate[1]', 'SMALLDATETIME'),
T.c.value('./HomeNumber[1]', 'NVARCHAR(20)'),
T.c.value('./CellNumber[1]', 'NVARCHAR(20)'),
(SELECT dt.DriverTypeId
FROM DriverType dt
WHERE dt.DriverTypeName LIKE '%' + T.c.value('./DriverType[1]', 'NVARCHAR(20)') + '%'),
@ISDId, @UserName, @dtCurrent, @UserName, @dtCurrent,
T.c.value('./PinCode[1]', 'NVARCHAR(20)')
FROM
@xmlDoc.nodes('/Drivers/Driver') T (c)
WHERE
(T.c.value('./Id[1]', 'NVARCHAR(20)') IS NOT NULL)
AND (T.c.value('./Id[1]', 'NVARCHAR(20)') <> '')
DECLARE newDriverCursor CURSOR FAST_FORWARD FOR
SELECT
t.DriverExternalId, t.DriverName, t.HireDate,
t.HomeNumber, t.CellNumber, t.DriverTypeId,
t.CreatedBy, t.DtCreated, t.LastUpdatedBy, t.DtLastUpdated,
t.PINCode
FROM
@DriverToImport t
WHERE
(t.IsNew = 1)
OPEN newDriverCursor
FETCH NEXT FROM newDriverCursor INTO @DriverId, @DriverName, @HireDate, @HomeNumber, @CellNumber, @DriverTypeId, @CreatedBy, @DtCreated, @LastUpdatedBy, @DtLastUpdated, @PINCode
WHILE (@@fetch_status = 0)
BEGIN
INSERT INTO dbo.Driver (DriverExternalId, DriverName, EmployeeNumber, HireDate, HomeNumber, CellNumber, DriverTypeId, ISDId, CreatedBy, DtCreated, LastUpdatedBy, DtLastUpdated, PINCode, IsActive, ResetPIN)
VALUES (@DriverExternalId, @DriverName, @DriverExternalId, @HireDate, @HomeNumber, @CellNumber, @DriverTypeId, @ISDId, @CreatedBy, @DtCreated, @LastUpdatedBy, @DtLastUpdated, @PINCode, 1, 0)
END
我知道过去我使用带有 SQL 变量的合并语句来进行批量插入。这也很好用,但需要为每个变量创建一个 table 变量。所以我的问题是 SQL Server 2016 是否有更强大的方法来处理批量插入?
术语 "bulk insert" 相当含糊,所以这取决于您的意思。根据您的描述,听起来您可能想查看 SQL Server side and from the .Net Framework side 中的 Table Valued Parameters。将 XML 字符串或定界字符串直接传递给存储过程并在存储过程中进行 XML 分解的旧方法本质上是 TVP 旨在取代的方法。从概念上讲,它的作用是允许您将 .Net DataTable 作为参数提交给存储过程 whole-hog。
不过,我也能想到bulk insert的其他含义。有 SqlBulkCopy class, which allows you to insert a DataTable as a single step fairly efficiently. There's also the BULK INSERT SQL statement,主要用于加载 CSV 文件。此外,还有 SSIS,它是一个完整的 ETL 包。如果您需要的逻辑比 BULK INSERT 允许的更多,或者需要进行额外的映射,有些人已经使用 SSIS 在系统之间完成了。
所以,就像我说的,这在某种程度上取决于 "bulk insert" 的意思。