【发布时间】:2020-09-11 18:11:44
【问题描述】:
我的本地 PC 上有一个 txt 文件,必须对其进行检查,然后使用 ADODB 的 MS Access 中的存储过程将其逐行上传到 SQL Server 2016。看起来 Access 总是快速运行 2 行,然后短暂停止。
在 MS Access 中,我正在使用此功能:
Public Function ImportData(FileString As String)
Dim WholeLine As String
Dim cc As Variant
Dim sapPurchaseDocument As String
Dim sapPartNumber As String
Dim sapPartName As String
Dim sapDocumentDate As String
Dim sapSupplier As String
Dim sapPlant As String
Dim sapSLoc As String
Dim sapQuantity As Double
Dim sapUOM As String
Dim sapTargetQuantity As Double
Dim sapDeliveryDate As String
Dim sapPrevQuantity As Double
Dim sapReceivedQuantity As Double
Dim sapIssuedQuantity As Double
Dim sapDeliveredQuantity As Double
Dim sapPurchaseRequisition As String
Dim sapPurchaseRequisitionItem As String
Dim sapCreationIndicatior As String
Dim sapNoOfPositions As Double
Dim totalCount As Integer
Dim sapPurchaseDocumentItem As String
Dim rs As New ADODB.Recordset
Call GetConnection
Set rs.ActiveConnection = myCN
If Right(FileString, 3) = "txt" Then
totalCount = GetRowCount(FileString)
Open FileString For Input As #1
i = 0
Do While Not EOF(1)
Line Input #1, WholeLine
If Left(WholeLine, 3) = "| 4" Then
'Debug.Print WholeLine
cc = Split(WholeLine, "|")
sapPurchaseDocument = Trim(cc(1))
sapPartNumber = Trim(Replace(cc(2), ".", ""))
sapPartName = Trim(Replace(cc(3), "'", ""))
sapDocumentDate = Right(cc(4), 4) & "-" & Mid(cc(4), 4, 2) & "-" & Left(cc(4), 2)
sapSupplier = cc(5)
sapPlant = cc(6)
sapSLoc = cc(7)
sapQuantity = Replace(cc(8), ",", "")
sapUOM = Trim(cc(9))
sapTargetQuantity = Replace(cc(10), ",", "")
sapDeliveryDate = Right(cc(11), 4) & "-" & Mid(cc(11), 4, 2) & "-" & Left(cc(11), 2)
sapPrevQuantity = cc(12)
sapReceivedQuantity = Replace(cc(13), ",", "")
sapIssuedQuantity = Replace(cc(14), ",", "")
sapDeliveredQuantity = Replace(cc(15), ",", "")
sapPurchaseRequisition = Trim(cc(16))
sapPurchaseRequisitionItem = Trim(cc(17))
sapCreationIndicatior = cc(18)
sapNoOfPositions = cc(19)
sapPurchaseDocumentItem = Trim(cc(20))
strSQL = "spInsertUpdateSAPME2M '" & sapPurchaseDocument & "', '" & sapPartNumber & "', '" & sapPartName & "', '" & _
sapDocumentDate & "', '" & sapSupplier & "', '" & sapPlant & "', '" & sapSLoc & "', " & _
sapQuantity & ", '" & sapUOM & "', " & sapTargetQuantity & ", '" & sapDeliveryDate & "', " & _
sapPrevQuantity & ", " & sapReceivedQuantity & ", " & sapIssuedQuantity & ", " & _
sapDeliveredQuantity & ", '" & sapPurchaseRequisition & "', '" & sapPurchaseRequisitionItem & "', '" & _
sapCreationIndicatior & "', '" & sapNoOfPositions & "', '" & sapPurchaseDocumentItem & "'"
rs.Open (strSQL)
DoEvents
End If
i = i + 1
Debug.Print i
Forms!frm_Overview.lblStatus.Caption = "Record " & i & " of " & totalCount & " loaded. Please wait!"
DoEvents
'Refresh
Loop
MsgBox "Import done"
End If
Close #1
End Function
在 SQL Server 上,我有一个如下所示的存储过程:
USE [MOBILEPRINT]
GO
/****** Object: StoredProcedure [dbo].[spInsertUpdateSAPME2M] Script Date: 5/25/2020 11:39:31 AM ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
CHANGE NO ACTION
ALTER PROCEDURE [dbo].[spInsertUpdateSAPME2M]
-- Add the parameters for the stored procedure here
@sapPurchaseDocument varchar(50),
@sapPartNumber varchar(50),
@sapPartName varchar(300),
@sapDocumentDate date,
@sapSupplier varchar(50),
@sapPlant varchar(100),
@sapSLoc varchar(50),
@sapQuantity float,
@sapUOM varchar(50),
@sapTargetQuantity float,
@sapDeliveryDate date,
@sapPrevQuantity float,
@sapReceivedQuantity float,
@sapIssuedQuantity float,
@sapDeliveredQuantity float,
@sapPurchaseRequisition varchar(50),
@sapPurchaseRequisitionItem varchar(50),
@sapCreationIndicatior varchar(50),
@sapNoOfPositions varchar(50),
@sapPurchaseDocumentItem varchar(50)
AS
BEGIN TRANSACTION
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @RESULT int
DECLARE @UPDATE_CHECK int
DECLARE @UpdateDate datetime = GetDate()
BEGIN
SELECT @RESULT = COUNT(sapPurchaseDocument) FROM SAP_ME2M WHERE sapPurchaseDocument = @sapPurchaseDocument AND sapPartNumber = @sapPartNumber
IF ISNULL(@RESULT,0) = 0
BEGIN
INSERT INTO SAP_ME2M (
sapPurchaseDocument,
sapPartNumber,
sapPartName,
sapDocumentDate,
sapSupplier,
sapPlant,
sapSLoc,
sapQuantity,
sapUOM,
sapTargetQuantity,
sapDeliveryDate,
sapPrevQuantity,
sapReceivedQuantity,
sapIssuedQuantity,
sapDeliveredQuantity,
sapPurchaseRequisition,
sapPurchaseRequisitionItem,
sapCreationIndicatior,
sapNoOfPositions,
ChangeDate,
sapPurchaseDocumentItem)
VALUES
(@sapPurchaseDocument, @sapPartNumber, @sapPartName, @sapDocumentDate, @sapSupplier, @sapPlant,
@sapSLoc, @sapQuantity, @sapUOM, @sapTargetQuantity, @sapDeliveryDate, @sapPrevQuantity,
@sapReceivedQuantity, @sapIssuedQuantity, @sapDeliveredQuantity, @sapPurchaseRequisition,
@sapPurchaseRequisitionItem, @sapCreationIndicatior, @sapNoOfPositions, @UpdateDate, @sapPurchaseDocumentItem)
END
ELSE
SELECT @UPDATE_CHECK = COUNT(*) FROM SAP_ME2M WHERE
sapPurchaseDocument = @sapPurchaseDocument AND
sapPartNumber = @sapPartNumber AND
sapPartName = @sapPartName AND
sapDocumentDate = @sapDocumentDate AND
sapSupplier = @sapSupplier AND
sapPlant = @sapPlant AND
sapSLoc = @sapSLoc AND
sapQuantity = @sapQuantity AND
sapUOM = @sapUOM AND
sapTargetQuantity = @sapTargetQuantity AND
sapDeliveryDate = @sapDeliveryDate AND
sapPrevQuantity = @sapPrevQuantity AND
sapReceivedQuantity = @sapReceivedQuantity AND
sapIssuedQuantity = @sapIssuedQuantity AND
sapDeliveredQuantity = @sapDeliveredQuantity AND
sapPurchaseRequisition = @sapPurchaseRequisition AND
sapPurchaseRequisitionItem = @sapPurchaseRequisitionItem AND
sapCreationIndicatior = @sapCreationIndicatior AND
sapNoOfPositions = @sapNoOfPositions AND
sapPurchaseDocumentItem = @sapPurchaseDocumentItem
IF @UPDATE_CHECK = 0
BEGIN
UPDATE SAP_ME2M SET
sapPartName = @sapPartName ,
sapDocumentDate = @sapDocumentDate ,
sapSupplier = @sapSupplier ,
sapPlant = @sapPlant ,
sapSLoc = @sapSLoc ,
sapQuantity = @sapQuantity ,
sapUOM = @sapUOM ,
sapTargetQuantity = @sapTargetQuantity ,
sapDeliveryDate = @sapDeliveryDate ,
sapPrevQuantity = @sapPrevQuantity ,
sapReceivedQuantity = @sapReceivedQuantity ,
sapIssuedQuantity = @sapIssuedQuantity ,
sapDeliveredQuantity = @sapDeliveredQuantity ,
ChangeDate = @UpdateDate
WHERE
sapPartNumber = @sapPartNumber AND
sapPartName = @sapPartName AND
sapDocumentDate = @sapDocumentDate AND
sapSupplier = @sapSupplier AND
sapPlant = @sapPlant AND
sapSLoc = @sapSLoc AND
sapPurchaseDocumentItem = @sapPurchaseDocumentItem
END
END
COMMIT TRANSACTION WITH (DELAYED_DURABILITY = ON);
我必须上传大约 30000 条记录,目前需要一个多小时。
如果您有任何建议,请告诉我。
【问题讨论】:
-
不要通过调用存储过程 3.000 次来处理插入,这势必会很慢。相反,使用(临时)表并在 SQL 服务器端处理它。使用带有批量插入的断开连接的记录集以获得最佳性能。为了进一步的改进,插入和更新都使用
MERGE,不要在单独的语句中这样做,特别是不要使用SELECT COUNT两次。 -
看起来存储过程不是问题,我尝试使用语句
Docmd.TransferDatabase acExport ......将本地表中的所有数据复制到 SQL Server 上,这也需要数年时间,任何人都建议转移从 MS Access 到 SQL Server 的本地表快吗? -
如前所述,使用带批量插入的断开连接的记录集。
-
你能添加一个例子吗?从未使用过断开连接的 rs
-
知道了!超级感谢埃里克!现在我每秒执行大约 200 条记录,而之前是每秒 2 条记录!谢谢
标签: sql-server performance ms-access insert adodb