Do new ADODB recordSet's create a new connection? - vb.net

I want to avoid creating multiple concurrent connection and I can't figure out how to tell what's going on behind the scenes.
Ex.
Sub TestConnections()
Dim conn As ADODB.Connection
Dim qry1 As String
Dim qry2 As String
Dim rs1 As New ADODB.RecordSet
Dim rs2 As New ADODB.RecordSet
conn = New ADODB.Connection
conn.ConnectionString = "<insert connection details>"
conn.open(conn.ConnectionString)
qry1 = "SELECT * FROM SomeTable;"
qry2 = "SELECT * FROM SomeOtherTable;"
rs1.Open(qry1,conn)
rs2.Open(qry2,conn)
End
Do I have two open connections right now, or are the two open record sets sharing the same connection?

They will be sharing the same connection, and holding 2 record sets for different queries.
The reason for this is because the connection object is the actual connection that the query gets sent across, and since it's the same object passed, it's the same connection that will handle both queries, although the recordset is returned and stored into the different variables.

Related

Conection Azure Databricks - VBA

Anyone know if it's possible to connect and manipulate the database in a cluster in Azure Databricks by the command ADODB in VBA?
I want to Insert new values in a table in my database as they are inserted in the worsheet.
I know that I can do this using SQL Server, but haven't found a way using Databricks.
In SQL Server, I 'd something like this to start with:
'''Sub DBRegister()
Dim MDB As New ADODB.Connection
Dim RS As New ADODB.Recordset
Dim FD As ADODB.Field
Dim SQL As String
Dim w As Worksheet
MDB.Open "DRIVER={SQL Server};SERVER=xxx.xx.200.168;UID=xxxxxx;PWD=xxxx"
'''
Once you get the DSN established as posted above this code should create the connection and allow to query for a recordset.
Dim cn as ADODB.Connection
Dim rs as ADODB.Recordset
Set cn = New ADODB.Connection
cn.Open "DSN=DSNNAMEHERE;UID=token;Password=ACCESSTOKENHERE"
rs.open "SELECT * From TableName"

PostgreSQL & Access -- Connecting at start vs. Connect when needed

I have a PostgreSQL 9.5 database with an Access 2016 front-end, using an ODBC driver to connect the two. If I wanted to query data, I would start with the following commands:
Dim conn As New ADODB.Connection
conn.Open "Driver={PostgreSQL ANSI};Server=localhost;Database=[name];User Id=[UID];Password=[pass];"
Dim cmd As New ADODB.Command
cmd.ActiveConnection = conn
My question is this: Is there any reason why I shouldn't establish this connection the moment the application opens, using that connection whenever I need to run a query, as opposed to opening and closing the connection each time I run a query?
I'm unsure what, if any, overhead is involved in establishing such a connection in Access, and I've been unable to find any information on the topic. Apologies if this is a naive question.
I the connection is cached by Access anyway.
Once you touch, or open any linked table, then the connection is now active, and re-used by Access.
In general if the query is against a single table, then there little reason to not just code against the linked table.
Eg:
Dim rst As DAO.Recordset
Dim strSQL As String
strSQL = "select * from tblInvoices where invoiceNum = 13355"
Set rst = CurrentDb.OpenRecordset(strSQL)
If you using a pass-though query, then this works well:
Sub Test555()
Dim rst As DAO.Recordset
With CurrentDb.QueryDefs("qryPass")
.SQL = "select * from tblInvoices where invoiceNum = 13355"
Set rst = .OpenRecordset
End With
End Sub
The reason for above is you thus don’t mess or have to bother with connection strings in your code.
Just ensure that you table re-link code also re-links any pass-through query.

SQL Management Studio 2012 with Excel vba connection string set up

I would like to set up a vba code that would connect to sql management studio 2012 a run the query, which I would specify in the vba code. I have read every similar question here on stack overflow but when I try to replicate them, I always get an error, ussualy that the login failed for user.
I think I am setting up the string connection wrong. Also, I would need the user authentication by Windows authentication.
I know the database name, server name and my user name.
This is the code I am using and which is giving me an error.
Sub ConnectionExample6()
Dim cnn As ADODB.Connection
Dim rs As ADODB.Recordset
Set cnn = New ADODB.Connection
' Open a connection by referencing the ODBC driver.
cnn.ConnectionString = "driver={SQL Server};" & _
"server=SERVER NAME;uid=USER ID;pwd=MyPassword;database=DATABASE NAME"
cnn.Open
' Create a Recordset by executing an SQL statement.
Set rs = cnn.Execute("Select top 100 * from "TABLE NAME" aac " & _
"where aac.EffectiveDate = '10/04/16'")
' Close the connection.
rs.Close
End Sub
Can someone walk me through the connection string and how to set it up step by step? Thank you.
Authentication
If you're connecting to SQL Server, you should prefer Windows Authentication if that's available: you create a Login at server level for a group of Active Directory users, and then you create a Windows-Authenticated User in your database using that login.
That way you are keeping passwords and usernames out of hard-coded strings, and let the network deal with authentication.
Assuming you don't want to be maintaining passwords in dozens of copies of macro-enabled workbooks across your network, you'll want to use Windows Authentication.
Integrated Security=SSPI; Persist Security Info=True;
Server
Connection strings are annoying - seems there's a different format/wording for every single different thing that's able to parse them!
Since you're using ADODB, you'll want to specify a Provider, a Data Source and, optionally, an Initial Catalog:
Provider=SQLOLEDB.1; Data Source=SQL Server instance name; Initial Catalog=Database name;
Who?
Each connection can be monitored on the server; when building your connection string you can optionally specify a Workstation ID to identify the machine the connection is for.
Workstation ID=computer name;
You can get the computer name by fetching the environment variable value, using Environ$:
Private Function GetWorkstationId() As String
GetWorkstationId = Environ$("ComputerName")
End Function
Given a SQL Server instance named SomeSqlServer, a database named SomeDatabase, and using Windows Authentication, the ADODB connection string would look like this:
Dim connString As String
connString = "Provider=SQLOLEDB.1; Data Source=SomeSqlServer; Initial Catalog=SomeDatabase; Integrated Security=SSPI; Persist Security Info=True;"
Given SQL Authentication (with a hard-coded user name and password) for SomeUser with SomePassword:
connString = "Provider=SQLOLEDB.1; Data Source=SomeSqlServer; Initial Catalog=SomeDatabase; UID=SomeUser; PWD=SomePassword;"
Commands
You don't want to be concatenating arbitrary user input into a WHERE clause; avoid executing an SQL string directly from the ADODB.Connection object.
Instead, create an ADODB.Command, and parameterize your query.
Dim sql As String
sql = "SELECT Foo, Bar FROM dbo.FooBars WHERE Foo = ? AND DateInserted > ?"
Here we have 2 parameters.
First we create the command:
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
cmd.ActiveConnection = conn
cmd.CommandType = adCmdText
cmd.CommandText = sql
Then its parameters, assuming we have their respective values in param1Value and param2Value local variables:
Dim param1 As ADODB.Parameter ' a string parameter
Set param1 = New ADODB.Parameter
param1.Type = adVarWChar
param1.Direction = adParamInput
param1.Size = Len(param1Value)
param1.Value = param1Value
cmd.Parameters.Append param1
Dim param2 As ADODB.Parameter ' a date parameter
Set param2 = New ADODB.Parameter
param2.Type = adDate
param2.Direction = adParamInput
param2.Value = param2Value
cmd.Parameters.Append param2
Then we retrieve the recordset by executing the command:
Dim results As ADODB.Recordset
Set results = cmd.Execute
Of course this looks very verbose, but it can easily be refactored into functions dedicated to creating a parameter given a value of a certain type.
As a result, you avoid this situation, because you're no longer executing arbitrary user input concatenated into a query:

VBA Connection from Excel 2010 to SQL Server 2008

i'm pretty new to SQL and VBA, so please forgive any audacity the code below may contain. I am working with code written in Excel's VBA. Eventually, the data from the user form in excel will be entered into a SQL database I have created using SQL Server 2008. Right now, I am just trying to open the connection to the SQL database and enter hard coded values into the db. Unfortunately, this has been much more of a challenge than I expected. I have tried playing around with the connection string a few different ways but have had no luck. When the form runs, I get no errors and I can see the data was added into the appropriate excel worksheet (but no changes in the SQL DB). I can see the db on SQL Server Management Studio and add rows from there, but I am unable to add a row to the db via this code. The db is protected solely by windows authentication. Any help would be greatly appreciated.
Sub ConnectSqlServer()
'********SPC DATABASE CONNECTION**********************
'write slurry information to database
'spc_date, mix_type, slurry_lot_num, mixer_num, shift, oper
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sConnString As String
'Create connection string
sConnString = "Provider=sqloledb; Server=SERV; Database=db; Trusted_Connection=True;"
'Create the Connection and Recordset objects
Set oConn = New ADODB.Connection
Set rs = New ADODB.Recordset
'Open connection and execute
conn.Open sConnString
Set rs = conn.Execute("INSERT INTO TBL (col1, col2) VALUES ('val', 'val');")
'Clean up
If CBool(conn.State And adStateOpen) Then conn.Close
Set conn = Nothing
Set rs = Nothing
End Sub
When inserting data, you don't need a recordset object, since an INSERT statement doesn't return a recordset. Instead, try using a command object instead. The command object gives you more control over how your SQL statement is passed to the server, and it also gives you a way to test whether any records were inserted.
I'd also recommend setting Option Explicit at the top of each module, since it will stop you from making mistakes with variables (for instance, you have both conn and oConn in your code, which I don't think you intended.
Here are my edits to your code. It's untested, but I think I've got it right. If it runs without any errors, and recordsAffected returns 1, but there's still nothing on the server, then we'll have to do some more digging.
Sub ConnectSqlServer()
'********SPC DATABASE CONNECTION**********************
'write slurry information to database
'spc_date, mix_type, slurry_lot_num, mixer_num, shift, oper
Dim conn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim sConnString As String
Dim recordsAffected as Long
'Create connection string
sConnString = "Provider=sqloledb; Server=SERV; Database=db; Trusted_Connection=True;"
'Open connection and execute
conn.Open sConnString
With cmd
.ActiveConnection = conn
.CommandType = adCmdText
.CommandText = "INSERT INTO TBL (col1, col2) VALUES ('val', 'val');"
.Execute recordsAffected 'Includes a return parameter to capture the number of records affected
End With
Debug.Print recordsAffected 'Check whether any records were inserted
'Clean up
If CBool(conn.State And adStateOpen) Then conn.Close
Set cmd = Nothing
Set conn = Nothing
End Sub

Execute Query from Access via Excel Query in VBA

Access has saved a query that was designed with the query builder called 'myQuery'. The database is connected to the system via ODBC connection. Macros are all enabled.
Excel Has makes a ADODB connection to connect to the database via
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Set con = New ADODB.Connection
With con
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Open "MyDatabase.accdb"
End With
Usually you would go ahead and just write your SQL, which is perfectly fine and then just do something like
Dim sqlQuery As String
sqlQuery = "SELECT * FROM myTable"
Set rs = New ADODB.Recordset
rs.Open sqlQuery, con, ...
But I want to access the query that I saved in the access database. So how do I call the saved query in the database that I just connected.
Tried already
con.Execute("EXEC myQuery") but that one told me it could not be find myQuery.
rs.Open "myQuery", con but that one is invalid and wants SELECT/etc statements from it
I think you can treat it like a stored procedure.
If we start right before Dim sqlQuery As String
Dim cmd as new ADODB.Command
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "myQuery"
cmd.ActiveConnection = con
Set rs = cmd.Execute()
Then pickup your recordset work after this.
You were nearly there:
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Set con = New ADODB.Connection
With con
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Open "z:\docs\MyDatabase.accdb"
End With
con.Execute "MyQuery"
Just leave out Exec.
You can add parameters, too, this is a little old, but should help: update 2 fields in Access database with Excel data and probably a Macro
I was able to run an update query that was already saved in Access using:
Connection.Execute "My_Update_Query_Already_Saved_In_Access", adExecuteNoRecords, adCmdStoredProc
This gave me errors until I replaced spaces in the query name with underscores in both the Access database and the execute statement.
This is sort of a hack job, but you can query a query. That is, replace your sql string with the following:
sqlQuery = "SELECT * FROM QueryName;"
Before running this, one must ensure that the Access Database has been saved ie. press Ctrl+S (it is not sufficient that the query was run in Access).
Long time since this thread was created. If I understand it correctly, I might have something useful to add. I've given a name to what the OP describes, that being the process of using SQL from a query saved in an ACCDB to run in VBA via DAO or ADOBD. The name I've given it is "Object Property Provider", even with the acronym OPP in my notes, and for the object name prefix/suffix.
The idea is an existing object in an ACCDB (usually a query) provides a property (usually SQL) that you need to use in VBA. I slapped together a function just to suck SQL out of queries for this; see below. Forewarning: sorry, but this is all in DAO, I don't have much use for ADODB. Hope you will still find the ideas useful.
I even went so far as to devise a method of using/inserting replaceable parameters in the SQL that comes from these OPP queries. Then I use VBA.Replace() to do the replacing before I use the SQL in VBA.
The DAO object path to the SQL of a query in an ACCDB is as follows:
mySqlStatement = Access.Application.CurrentDb.QueryDefs("myQueryName").SQL
The way I use replaceable parameters is by evaluating what needs to be replaced, and choosing an unusual name for the paramater that cannot possibly exist in the real database. For the most part, the only replacements I've made are field or table names, or the expressions of WHERE and HAVING clauses. So I name them things like "{ReplaceMe00000001}" and then use the Replace() function to do the work...
sqlText = VBA.Replace(sqlText, "{ReplaceMe00000001}", "SomeActualParameter")
...and then use the sqlText in VBA. Here's a working example:
Public Function MySqlThing()
Dim sqlText as String
Dim myParamater as String
Dim myExpression as String
'Set everything up.
sqlText = getSqlTextFromQuery("myQuery")
myParameter = "{ReplaceMe00000001}"
myExpression = "SomeDateOrSomething12/31/2017"
'Do the replacement.
sqlText = VBA.Replace(sqlText, myParameter, myExpression)
'Then use the SQL.
db.Execute sqlText, dbFailOnError
End Function
Function getSqlTextFromQuery(ByVal oppName As String) As String
Dim app As Access.Application
Dim db As DAO.Database
Dim qdefs As DAO.QueryDefs
Dim qdef As DAO.QueryDef
Dim sqlText As String
Set app = Access.Application
Set db = app.CurrentDb
Set qdefs = db.QueryDefs
Set qdef = qdefs(oppName)
oppGetSqlText = qdef.SQL
End Function