【发布时间】:2016-12-16 21:08:00
【问题描述】:
我很好奇是否有人可以提出更好的批量插入方法。在我目前的工作中,我们正在构建作为变量传递给存储过程的 xml 字符串,然后创建一个临时表并插入 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 变量的合并语句来进行批量插入。这也很好用,但需要为每个变量创建一个表变量。所以我的问题是在 SQL Server 2016 中是否有更强大的方法来处理批量插入?
【问题讨论】:
-
您应该使用 CTE 或合并语句。避免使用光标……即使有人拿着枪对着你,也不要使用光标:P
-
我没有看到任何光标,顺便说一句,简单的 INSERT INTO 语句有什么问题?
-
我只是省去了整个过程 - 更新为包含更多的 SPROC - 我同意我也不喜欢使用它们,但为了做到这一点,我需要提供一个可行的替代方案- 调查 CTE
-
简单的插入语句不起作用的原因是,在某些过程中,我们会为每个行更新/插入尝试提供详细的反馈。因此,在这些情况下,逻辑将应用于每个通道以更新临时日志表。在这些情况下,我不知道如何避免使用游标 - SQL 不是我的强项:(
标签: sql-server bulkinsert