Sql VBA新数据库连接
如何更改下面的代码以防止在屏幕截图中看到的内容 我正在使用以下代码运行宏Sql VBA新数据库连接,sql,excel,adodb,vba,Sql,Excel,Adodb,Vba,如何更改下面的代码以防止在屏幕截图中看到的内容 我正在使用以下代码运行宏 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=
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
With Sheets(“FVols”).QueryTables.Add(连接:=rec1,目标:=Sheets(“FVols”).Range(“A1”))
.name=“数据”
.FieldNames=True
.Refresh BackgroundQuery:=True完成连接变量后是否释放该变量?i、 e
Set rec1 = Nothing
否则连接将无法完全关闭。您只需打开一次连接。这意味着您可以在一个活动连接上执行多个查询。必须关闭连接并释放引用(特别是使用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
如果看不到更多的宏代码,很难回答,但似乎您从未关闭连接,因此,是的,每次宏运行时,您都会创建一个新连接。@Tony,我在结尾写了conn.close,但它仍然会创建新连接(rec1.close会使宏崩溃)。还有什么需要关闭的吗?我只是在代码中添加了这个(并设置conn=Nothing)。我仍然在截屏的窗口中获得新的连接。我只有一个查询,每次运行宏时只需要运行一次。如果我使用您的方法,我是否需要在每次运行宏时运行DbConnection?这将创建一个新连接?Thanks@frickskit好的,我现在明白了。我已经更新了我的答案,看一看