MS Access VBA Pass Through Query Connection String Error (ODBC) - sql

I am currently trying to write a pass through query using VBA that connects to an oracle database. Using the answer provided from SQL Server Passthrough query as basis for a DAO recordset in Access as a starting poing, I have the following VBA code.
Option Compare Database
Sub Test_PassThroughQuery()
Dim qdf As DAO.QueryDef, rst As DAO.Recordset
Set qdf = CurrentDb.CreateQueryDef("")
qdf.Connect = "ODBC;DSN=database_name;UID=username;PWD=password;DBQ=ADPR;DBA=W;APA=T;EXC=F;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;BTD=F;BNF=F;BAM=IfAllSuccessful;NUM=NLS;DPM=F;MTS=T;MDI=F;CSR=F;FWC=F;FBS=64000;TLO=O;MLD=0;ODA=F;"
qdf.SQL = "SELECT * FROM DATE_TABLE"
qdf.ReturnsRecords = True
Set rst = qdf.OpenRecordset
Debug.Print rst
rst.Close
Set rst = Nothing
Set qdf = Nothing
End Sub
However, this prompts an error Type mismatch on the Debug.Print rst.
For the connection string I am using the ODBC connection string from the Property tab.
EDIT Am I calling the Debug.print rst line incorrectly?

There are many ways to create pass-through queries. If you want to save a pass-through query in Access, you can set the first parameter of CreateQueryDef:
Sub Test_PassThroughQuery()
Dim qdf As DAO.QueryDef, rst As DAO.Recordset
Set qdf = CurrentDb.CreateQueryDef("MyPassthroughQuery")
qdf.Connect = "ODBC;DSN=database_name;UID=username;PWD=password;DBQ=ADPR;DBA=W;APA=T;EXC=F;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;BTD=F;BNF=F;BAM=IfAllSuccessful;NUM=NLS;DPM=F;MTS=T;MDI=F;CSR=F;FWC=F;FBS=64000;TLO=O;MLD=0;ODA=F;"
qdf.SQL = "SELECT * FROM DATE_TABLE"
qdf.ReturnsRecords = True
DoCmd.OpenQuery "MyPassthroughQuery"
End Sub
This creates a saved query, and opens it.
You could also query an external data source in Access, which allows you to use the query designer, and use local tables and external data in a single query:
SELECT *
FROM [ODBC;DSN=database_name;UID=username;PWD=password;DBQ=ADPR;DBA=W;APA=T;EXC=F;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;BTD=F;BNF=F;BAM=IfAllSuccessful;NUM=NLS;DPM=F;MTS=T;MDI=F;CSR=F;FWC=F;FBS=64000;TLO=O;MLD=0;ODA=F;].DATE_TABLE

Related

Why does an ms-access sql Pass Through not work in VBA

I am currently trying to write a select pass through query using VBA in Access 2016. If I use the manual option via the button Pass-Through and assign manually the dsn the following statement works.
SELECT top 1 dat_Kunden.Kunden_Status FROM dat_Kunden
The sql I want to pass through is changing so I want to create a VBA Function to execute it.
This is my current Function to execute a given sql statement
Function CreateSPT(strSQL As String)
Dim qdf As DAO.QueryDef, rs As DAO.Recordset
Set qdf = CurrentDb.CreateQueryDef("")
qdf.Connect = "ODBC;Driver=SQL Server;SERVER=xxx;DATABASE=yyy;UID=zzz" 'in the code this is the real data
qdf.SQL = strSQL
qdf.ReturnsRecords = True
Set rs = qdf.OpenRecordset()
If Not (rs.BOF And rs.EOF) Then rs.MoveFirst
Do Until rs.EOF
Debug.Print rs.Fields(0)
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Set qdf = Nothing
End Function
This does work.
Sub test_sql()
SQL = "SELECT CONVERT( date, GETDATE() ) AS qryTest"
CreateSPT (SQL)
End Sub
This statement which works via the manual pass through does not work
Sub test_sql2()
SQL = "SELECT top 1 dat_Kunden.Kunden_Status FROM dat_Kunden AS qryTest"
CreateSPT (SQL)
End Sub
The Error code is Run-time error '3146': ODBC -- call failed at this line:
Set rs = qdf.OpenRecordset()
I hope you have an idea where my mistake is... Thanks to all of you, learned a lot from you!
If you provide an alias, use it:
SQL = "SELECT Top 1 qryTest.Kunden_Status FROM dat_Kunden AS qryTest"
or ignore it:
SQL = "SELECT Top 1 Kunden_Status FROM dat_Kunden AS qryTest"

Access VBA: Recordset doesn't work with a specific query?

first off: I'm not an expert, I'm pretty much a noob at VBA.
onto my question:
So I'm using a Recordset in VBA, if the Recordset I open is a table or a simple query, it works,
but I have another query that I want to base that recordset on, but when I do that, it doesn't work.
The query I'm trying to use with the Recordset basically contains a field "user" that changes based on the textbox of a form. Is it not possible to open that query as recordset because it depends on the textbox of a form or am I missing something in the code?
Here my code for reference:
Dim db As Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("tblExample")
Do Until rs.EOF
Debug.Print rs.Fields("FieldExample")
rs.MoveNext
Loop
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
I also tried replacing "tblExample" with an SQL string that is basically the same as the query I'm trying to use, with no success. The query itself does work without any problems though.
The query I'm trying to use (shortened version):
SELECT Inventar.nutzName FROM Inventar WHERE (((Inventar.nutzName) Like "*" & [Formulare]![frmInventarNutzerFilter]![cbxNutzer] & "*"))
Your code cannot "see" the parameter value, so you will have to pass this explicetly:
Dim db As DAO.Database
Dim qd As DAO.QueryDef
Dim rs As DAO.Recordset
Set db = CurrentDb
Set qd = db.QueryDefs("YourQuery")
qd.Parameters(0).Value = [Forms]![frmInventarNutzerFilter]![cbxNutzer]
Set rs = qd.OpenRecordset()
Do Until rs.EOF
Debug.Print rs.Fields("FieldExample")
rs.MoveNext
Loop
rs.Close
qd.Close
db.Close
Set rs = Nothing
Set db = Nothing

MS Access 2016 SQL in VBA

I'm sure I'm making a simple mistake. I have a SQL Server with tables that I have linked in MS Access. I am trying to run a SQL query in Form OnLoad to populate a text box based on a value in my form.
Below is my code. The field I want returned TE is varchar in MSSQL and short text in Access. I am getting a 'Type Mismatch' on the textbox. When I try outputting to a MsgBox I get:
'rst!TE not in collection'.
TN and TN_1 are smallint, in Access they are Number.
Dim rst As DAO.Database
Set rst = CurrentDb
rst.OpenRecordset "SELECT dbo_STCH.TE FROM dbo_STCH RIGHT JOIN dbo_SCVR ON dbo_STCH.TN = dbo_SCVR.TN_1 WHERE dbo_SCVR.TN_1=99;"
Me.Text22.Text = rst!TE
rst.Close
Set rst = Nothing
You are conflating DAO recordsets and databases and hence the message is correct as the item is not found in collection. Simply initialize rst as a recordset and assign it to OpenRecordset call.
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("SELECT dbo_STCH.TE FROM dbo_STCH" _
& " RIGHT JOIN dbo_SCVR ON dbo_STCH.TN = dbo_SCVR.TN_1" _
& " WHERE dbo_SCVR.TN_1=99;")
Me.Text22.Text = rst!TE
rst.Close
Set rst = Nothing
You have to use rst.MoveFirst to move to the first record of the opened recordset before reading any values from it.
Also as the answer above you have to Set rst = CurrentDb.OpenRecordset

Execute a SQL Server stored procedure from MS Access

I use MS Access 2013 and SQL Server 2012. I have connected my SQL Server database to MS Access. I connect to SQL Server via SQL Server Authentication. I want to execute a stored procedure with a value entered into a textbox in one of my forms. I have been trying to do it for ages now but nothing that I found on this website works for me. Can anyone please help me and give me some tips as to how to write a basic VBA code to execute the procedure? Please help!!!
Probably the most straightforward way is to create a temporary pass-through query using a DAO.QueryDef object. If you have an existing linked table in Access then you can use its .Connect property (ODBC connection information). All you need to do is set the .SQL property of the QueryDef to call (EXEC) the stored procedure, like this:
Option Compare Database
Option Explicit
Private Sub Command2_Click()
Dim cdb As DAO.Database, qdf As DAO.QueryDef
Set cdb = CurrentDb
Set qdf = cdb.CreateQueryDef("")
' get .Connect property from existing ODBC linked table
qdf.Connect = cdb.TableDefs("dbo_myContacts").Connect
qdf.sql = "EXEC dbo.addContact N'" & Replace(Me.Text0.Value, "'", "''") & "'"
qdf.ReturnsRecords = False
qdf.Execute dbFailOnError
Set qdf = Nothing
Set cdb = Nothing
End Sub
So, for example, if the Text0 text box contains Thompson then the QueryDef will execute
EXEC dbo.addContact N'Thompson'
and if the text box contains O'Rourke then the QueryDef will execute
EXEC dbo.addContact N'O''Rourke'
After Trial and error this one worked for me
> Private Sub UpdateItems_Click()
> Dim cdb As DAO.Database, qdf As DAO.QueryDef
> Set cdb = CurrentDb
> Set qdf = cdb.CreateQueryDef("")
> ' get .Connect property from existing ODBC linked table
> qdf.Connect = cdb.TableDefs("dbo_AccesLinkedTable").Connect
> qdf.SQL = "EXEC dbo.YourStoreProcedure"
> qdf.ReturnsRecords = False
> qdf.Execute dbFailOnError
> Set qdf = Nothing
> Set cdb = Nothing
>
> MsgBox "Records Updated!"
>
> End Sub

Terminating Query If Not Connection

I have a code that uploads data to a SQL server database, I am trying to add in an IF line of code saying if there is a connection then to continue, but if there is not a connection then to END. I am having a difficult time figuring out the wording and placement though. The beginning of the code that connects is:
Public Function Update()
Dim cdb As DAO.Database, qdf As DAO.QueryDef
Dim rs As DAO.Recordset
Dim err As DAO.Error
Const ConnectionString = _
"ODBC;" & _
"Driver={SQL Server Native Client 10.0};" & _
"Server=SERV;" & _
"Database=DB;" & _
"UID=ID;" & _
"PWD=PWD;"
Set cdb = CurrentDb
Set qdf = cdb.CreateQueryDef("")
Set rs = CurrentDb.OpenRecordset("CDData", dbOpenTable)
qdf.Connect = ConnectionString
Do While Not rs.EOF
While one can simple attempt to execute any query or command, the “time out” and delay to test for an active connection can result in a VERY LONG delay. As a result a wonderful trick exists that uses a DIFFERENT connection mechanism in Access and thus “reduces” the potential VERY long delay when attempting to use a saved query that is based on linked tables. (that "different" connection system occurs when you create a queryDef as opposed to a linked table or a query based on a linked table to sql server)
The follow code will return true or false if you have a working SQL connection:
Function TestLogin(strcon As String) As Boolean
On Error GoTo TestError
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
Set dbs = CurrentDb()
Set qdf = dbs.CreateQueryDef("")
qdf.Connect = strcon
qdf.ReturnsRecords = False
'Any VALID SQL statement that runs on server will work below.
qdf.SQL = "SELECT 1 as test"
qdf.Execute
TestLogin = True
Exit Function
TestError:
TestLogin = False
Exit Function
End Function
So in code you now with your connection string code go:
If TestLogIn(strConn) = false then
msgbox "no connection or logon invalid"
exit sub
End If
' record processing code goes here for successful logon/connection.