如何更改下面的代码以防止您在屏幕截图中看到的内容。
我正在使用以下代码运行宏
Dim conn As ADODB.Connection
Dim rec1 As ADODB.Recordset
Dim thisSql As String
Set conn = New ADODB.Connection
Dim sConn As String
sConn = "Provider=SQLOLEDB;Trusted_Connection=Yes;Server=xyz;Database=xyz;UID=xyz;PWD=xyz"
conn.Open sConn
' this is creating multiple connections.
Set rec1 = New ADODB.Recordset
rec1.Open thisSql, conn
运行 SQL Server 查询(大约 20 行长,包含 4 个连接)。一切都很好,除了运行几次后我的数据库管理员说我的查询加载了太多数据库。
现在,我的查询可能导致了问题,也可能是 Excel 开始同时运行多个连接。下面的屏幕截图可以证明这一点,并且数据库上的负载似乎随着时间的推移而增加。
如何建立数据库连接而不需要不断创建新连接?
有人在使用 Excel DB 宏时遇到过类似的问题吗?
更新
虽然下面的答案非常有用(特别是对于刚开始使用 VBA 的人来说),但我的查询占用负载的主要原因似乎是多个连接的组合,并且忽略了代码中的一行:
With Sheets("FVols").QueryTables.Add(Connection:=rec1, Destination:=Sheets("FVols").Range("A1"))
.name = "data"
.FieldNames = True
.Refresh BackgroundQuery:=True <<<<<<<<<<<<<<<<<<<<<<<-----
End With
您只需打开连接一次。从字面上看,这意味着您可以在一个活动连接上执行多个查询。您必须关闭连接并释放引用(特别是 ADODB)以避免遇到冲突和其他与连接相关的问题。
如果您知道要执行的查询,则可以创建一个数组(或集合)并将查询添加到队列中。
虽然您已经有一个开放的连接可供使用,但您可以继续执行查询。
扫描代码,你的和我的没有太大区别,所以你应该能够看到发生了什么以及在哪里。有不懂的地方请在评论里提问
Sub DbConnection()
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
Dim rs As ADODB.Recordset
Dim strConn As String
strConn = "Driver={SQL Server};Server=; Database=; UID=; PWD="
cn.Open strConn
Dim queryArr, i
queryArr = Array("SELECT * FROM [MyTable]", "SELECT * FROM [MyOtherTable]")
For i = LBound(queryArr) To UBound(queryArr)
ExecuteQuery queryArr(i), cn, rs
Next i
cn.Close
Set cn = Nothing
End Sub
Private Sub ExecuteQuery(query As Variant, ByRef cn As ADODB.Connection, ByRef rs As ADODB.Recordset)
Set rs = New ADODB.Recordset
With rs
.ActiveConnection = cn
.Open CStr(query)
Sheets(1).Range("A1").CopyFromRecordset rs
.Close
End With
Set rs = Nothing
End Sub
现在,您只需执行一次
DBConnection()
,数组中列出的所有查询都将被执行。
或者,如果您的查询是在运行时创建的,您可以将其作为参数传递给
DbConnection()
。
Sub DbConnection(queryQueue As Collection)
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
Dim rs As ADODB.Recordset
Dim strConn As String
strConn = "Driver={SQL Server};Server=HELIUM\PRI; Database=sourcedata; UID=tabula; PWD=Tabula123!"
cn.Open strConn
For i = 1 To queryQueue.Count
ExecuteQuery queryQueue.Item(i), cn, rs
Next i
cn.Close
Set cn = Nothing
End Sub
Private Sub ExecuteQuery(query As Variant, ByRef cn As ADODB.Connection, ByRef rs As ADODB.Recordset)
Set rs = New ADODB.Recordset
With rs
.ActiveConnection = cn
.Open CStr(query)
Sheets(1).Range("A1").CopyFromRecordset rs
.Close
End With
Set rs = Nothing
End Sub
您可以将您的连接声明为全局变量。现在,您可以根据需要多次运行
DBConnection()
,并且不会每次都创建新连接。相反,您将使用全局连接对象。
Option Explicit
Public cn As ADODB.Connection
Sub DbConnection()
Set cn = New ADODB.Connection
Dim rs As ADODB.Recordset
Dim strConn As String
strConn = "Driver={SQL Server};Server=; Database=; UID=; PWD="
cn.Open strConn
Set rs = New ADODB.Recordset
With rs
.ActiveConnection = cn
.Open "SELECT * FROM [MyTable]"
Sheets(1).Range("A1").CopyFromRecordset rs
.Close
End With
Set rs = Nothing
cn.Close
Set cn = Nothing
End Sub
完成连接变量后是否释放它?即
Set rec1 = Nothing
如果没有,连接将不会完全关闭。
错误 adodb 请重试与 454 通话,按 10 36473 25274 准备好 10