如何提高批量插入到 Access 中多列的 ODBC 链接表的性能?
How to increase performance for bulk INSERTs to ODBC linked tables in Access for multiple columns?
本题基于此题:How to increase performance for bulk INSERTs to ODBC linked tables in Access?
我对上面的 linked 主题有进一步的问题,因为我没有足够的分数来评论这个主题,所以我在这里创建了我的问题。
由于 Gord Thompson 的出色回答,他在上面的 link 中提供了以下代码。
Sub PtqTest()
Dim cdb As DAO.Database, rst As DAO.Recordset
Dim t0 As Single, i As Long, valueList As String, separator As String
t0 = Timer
Set cdb = CurrentDb
Set rst = cdb.OpenRecordset("SELECT MPO_REFERENCE FROM tblTempSmartSSP", dbOpenSnapshot)
i = 0
valueList = ""
separator = ""
Do Until rst.EOF
i = i + 1
valueList = valueList & separator & "(" & rst!MPO_REFERENCE & ")"
If i = 1 Then
separator = ","
End If
If i = 1000 Then
SendInsert valueList
i = 0
valueList = ""
separator = ""
End If
rst.MoveNext
Loop
If i > 0 Then
SendInsert valueList
End If
rst.Close
Set rst = Nothing
Set cdb = Nothing
Debug.Print "Elapsed time " & Format(Timer - t0, "0.0") & " seconds."
End Sub
Sub SendInsert(valueList As String)
Dim cdb As DAO.Database, qdf As DAO.QueryDef
Set cdb = CurrentDb
Set qdf = cdb.CreateQueryDef("")
qdf.Connect = cdb.TableDefs("METER_DATA").Connect
qdf.ReturnsRecords = False
qdf.sql = "INSERT INTO METER_DATA (MPO_REFERENCE) VALUES " & valueList
qdf.Execute dbFailOnError
Set qdf = Nothing
Set cdb = Nothing
End Sub
我的问题是,如果我想在插入期间包含多个列怎么办?例如,除了 MPO_REFERENCE,我还有其他名为 NEW_COLUMN 的列要插入到 METER_DATA
(来自 sql 服务器的 odbc linked table),我尝试对上述代码中的某些行进行修改,但失败了。抱歉,我是 SQL 和 VB 的新手,如果有人能提供帮助,我将不胜感激。谢谢。
...
Set rst = cdb.OpenRecordset("SELECT MPO_REFERENCE,NEW_COLUMN FROM tblTempSmartSSP", dbOpenSnapshot)
...
...
valueList = valueList & separator & "(" & rst!MPO_REFERENCE & "," & rst!NEW_COLUMN & ")"
...
...
qdf.sql = "INSERT INTO METER_DATA (MPO_REFERENCE,NEW_COLUMN) VALUES " & valueList
...
基本上,你明白了,代码是正确的。
但是您还必须考虑其他一些事项:
如果rst!NEW_COLUMN
为空,则将空字符串传递给SQL 命令,这将导致错误。
例如错误导致 SQL-string:
INSERT INTO METER_DATA (MPO_REFERENCE,NEW_COLUMN) VALUES (3, )
在构建 SQL 字符串之前检查 NEW_COLUMN 是否为空
如果NEW_COLUMN是字符串值,则必须用单引号括起来。这看起来像这样:
valueList = valueList & separator & "(" & rst!MPO_REFERENCE _
& ",'" & rst!NEW_COLUMN & "')"
第二个考虑可能也解决了第一个考虑,因为它将 ...VALUES (3, )...
更改为 ...VALUES (3, '')...
提供了一个空字符串插入。
我假设,MPO_REFERENCE
没有单引号,因为它是一个数字。
本题基于此题:How to increase performance for bulk INSERTs to ODBC linked tables in Access?
我对上面的 linked 主题有进一步的问题,因为我没有足够的分数来评论这个主题,所以我在这里创建了我的问题。
由于 Gord Thompson 的出色回答,他在上面的 link 中提供了以下代码。
Sub PtqTest()
Dim cdb As DAO.Database, rst As DAO.Recordset
Dim t0 As Single, i As Long, valueList As String, separator As String
t0 = Timer
Set cdb = CurrentDb
Set rst = cdb.OpenRecordset("SELECT MPO_REFERENCE FROM tblTempSmartSSP", dbOpenSnapshot)
i = 0
valueList = ""
separator = ""
Do Until rst.EOF
i = i + 1
valueList = valueList & separator & "(" & rst!MPO_REFERENCE & ")"
If i = 1 Then
separator = ","
End If
If i = 1000 Then
SendInsert valueList
i = 0
valueList = ""
separator = ""
End If
rst.MoveNext
Loop
If i > 0 Then
SendInsert valueList
End If
rst.Close
Set rst = Nothing
Set cdb = Nothing
Debug.Print "Elapsed time " & Format(Timer - t0, "0.0") & " seconds."
End Sub
Sub SendInsert(valueList As String)
Dim cdb As DAO.Database, qdf As DAO.QueryDef
Set cdb = CurrentDb
Set qdf = cdb.CreateQueryDef("")
qdf.Connect = cdb.TableDefs("METER_DATA").Connect
qdf.ReturnsRecords = False
qdf.sql = "INSERT INTO METER_DATA (MPO_REFERENCE) VALUES " & valueList
qdf.Execute dbFailOnError
Set qdf = Nothing
Set cdb = Nothing
End Sub
我的问题是,如果我想在插入期间包含多个列怎么办?例如,除了 MPO_REFERENCE,我还有其他名为 NEW_COLUMN 的列要插入到 METER_DATA (来自 sql 服务器的 odbc linked table),我尝试对上述代码中的某些行进行修改,但失败了。抱歉,我是 SQL 和 VB 的新手,如果有人能提供帮助,我将不胜感激。谢谢。
...
Set rst = cdb.OpenRecordset("SELECT MPO_REFERENCE,NEW_COLUMN FROM tblTempSmartSSP", dbOpenSnapshot)
...
...
valueList = valueList & separator & "(" & rst!MPO_REFERENCE & "," & rst!NEW_COLUMN & ")"
...
...
qdf.sql = "INSERT INTO METER_DATA (MPO_REFERENCE,NEW_COLUMN) VALUES " & valueList
...
基本上,你明白了,代码是正确的。
但是您还必须考虑其他一些事项:
如果
rst!NEW_COLUMN
为空,则将空字符串传递给SQL 命令,这将导致错误。例如错误导致 SQL-string:
INSERT INTO METER_DATA (MPO_REFERENCE,NEW_COLUMN) VALUES (3, )
在构建 SQL 字符串之前检查 NEW_COLUMN 是否为空
如果NEW_COLUMN是字符串值,则必须用单引号括起来。这看起来像这样:
valueList = valueList & separator & "(" & rst!MPO_REFERENCE _ & ",'" & rst!NEW_COLUMN & "')"
第二个考虑可能也解决了第一个考虑,因为它将 ...VALUES (3, )...
更改为 ...VALUES (3, '')...
提供了一个空字符串插入。
我假设,MPO_REFERENCE
没有单引号,因为它是一个数字。