My ultimate goal is to run sql queries against sql-server and capture the returned data in a spreadsheet. The following code roughly reflects my current set-up and it works. The design allows me to read sql codes from text files and submit it to a sql-server. "Sub ExecuteCRUD" submits a first sql script to prepare data and dumps the result into a temp table. "Function loadRecordset" submits a relatively simple select query and captures the returned data in a recordset, which I then use to populate a spreadsheet.
There are a couple "variables" in my setup that could potentially be relevant for discussion.
My 4 set of Sql Codes
The ConnectionString (Part of my vba code)
The rest of my vba codes
a. Dbo.ConnectionString = "Provider=MSDASQL;DRIVER=SQL Server;SERVER=myserver;UID=id;PWD=password;DATABASE=database;"
b. Dbo.ConnectionString = "Provider=SQLOLEDB;Data Source=myserver;Initial Catalog=database;User ID=id;Password=password;"
Initially, all I changed was the connection string. The immediate result was connection string version a works perfectly. Using b version, my setup would fail without any errors from sql-server.
Using Connection string version b, "Sub ExecuteCRUD" (data preparation step) would still work smoothly. I can verify that the temp table is created in tempdb as a result of my first sql script.
"Function loadRecordset" would run through the lines without any errors up to and including "rs.open". (I checked for errors, none whatsoever from the ado connection).
Only subsequent codes, when using the recordset to copy out the data would get an error: "Operation is not allowed when the object is closed."
Through some testing, I narrowed down the issue to the sql codes, sort of.
I have to reiterate here. My initial set of sql codes worked completely fine when using the ODBC provider. Things only went sideways using the OLEDB provider.
Using the OLEDB provider, the "offending" sql code was Use databaseABC. Furthermore, using ado, my setup submits 4 sets of sql codes to the sql server. The first set of sql codes prepares data (creating tables, inserting data, creating index, using while loops to populate data, using recursive ctes, etc). In this first set of sql codes, Use databaseABC was also included, and it would execute successfully. The other 3 set of sql codes submitted were only select queries aimed at obtaining data. When Use databaseABC was included in the select query sql codes, the operation failed without any errors. After I took out the Use databaseABC, everything would run correctly in the OLEDB provider world.
Use databaseABC is not a necessary part of the select queries. Using it saves me the trouble of specifying database names all the time in the join clauses.
At this point, my curiosity is two fold
- why Use databaseABC causes failures, specifically only when using OLEDB provider, more specifically only when running select queries.
- When the failure occurred, should sql-server or the driver generate any errors? What would be the proper way of checking and verifying that?
Private Dbo As New ADODB.Connection
Private rs As ADODB.Recordset
Public Sub ConnectServer()
If Dbo.State = adStateClosed Then
Dbo.ConnectionString = "Provider=SQLOLEDB;Data Source=*server*;" _
& "Initial Catalog=*database*;User ID=*id*;Password=*pwd*;"
Dbo.Open
End If
End Sub
Public Sub ExecuteCRUD(ByVal Sql As String)
On Error GoTo PANIC
Dbo.Execute Sql
Exit Sub
PANIC:
Debug.Print Err.Descript
Stop
End Sub
Public Function loadRecordset(ByVal Sql As String) As Long
On Error GoTo PANIC
Set rs = New ADODB.Recordset
With rs
.CursorLocation = adUseClient
.CursorType = adOpenStatic
.LockType = adLockReadOnly
.Source = Sql
Set .ActiveConnection = Dbo
End With
rs.Open
loadRecordset = rs.RecordCount
Exit Function
PANIC:
Debug.Print Err.Description
loadRecordset = 0
Stop
End Function