SQL Stored Procedure times out in Access - sql-server

The following SP times out when executed from Access VBA. It works fine when executed from the management console. If relevant, the server does has a high ping time:
Dim cnn As ADODB.Connection
Dim cmd As New ADODB.Command, rs As New ADODB.Recordset, param As New ADODB.Parameter
Dim fld As ADODB.Field
Dim stMessage As String
Set cnn = New ADODB.Connection
cnn.ConnectionString = "DRIVER=SQL Server;SERVER=server01;DATABASE=db_a;Trusted_Connection=Yes"
cnn.Open cnn.ConnectionString
Set cmd = New ADODB.Command
cmd.ActiveConnection = cnn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "we_ci_db.stprUpdateValuesInitial_A"
Set param = cmd.CreateParameter("#DataSet", adInteger, adParamInput, , stDataSet)
cmd.Parameters.Append param
rs.CursorType = adOpenStatic
rs.CursorLocation = adUseClient
rs.LockType = adLockOptimistic
Set rs = cmd.Execute
exit1:
Set cmd = Nothing
Set rs = Nothing
Exit Function

You can set the timeout using CommandTimeout property of ADODB.Command objects:
// set a very high number of seconds before timeout
cmd.CommandTimeout = 9999999

Related

Run SQL Server stored procedure from VBA

This is my stored procedure which works fine in SQL Server Management Studio.
exec GroupCommissions #GroupNumberEntry = '01142'
Should produce a table of data.
I'm trying to run it in vba using the following code:
Dim rs As ADODB.Recordset
Dim cnSQL As ADODB.Connection
Dim sqlcommand As ADODB.Command, prm As Object
Set cnSQL = New ADODB.Connection
cnSQL.Open "Provider=SQLOLEDB; Data Source=bddc1didw1;Initial Catalog=Actuarial; Trusted_connection=Yes; Integrated Security='SSPI'"
Set sqlcommand = New ADODB.Command
sqlcommand.ActiveConnection = cnSQL
sqlcommand.CommandType = adCmdStoredProc
sqlcommand.CommandText = "GroupCommissions"
Set prm = sqlcommand.CreateParameter("GroupNumberEntry", adParamInput)
sqlcommand.Parameters.Append prm
sqlcommand.Parameters("GroupNumberEntry").Value = "01142"
Set rs = New ADODB.Recordset
rs.CursorType = adOpenStatic
rs.LockType = adLockOptimistic
rs.Open sqlcommand
ActiveSheet.Range("a3").CopyFromRecordset rs
But it just returns blank and I can't work out what I'm doing wrong. Also is there a simpler way to do this?
As discussed below i've managed to fix the issue by adding SET NOCOUNT ON to the original stored procedure. My issue now is I want to do a second stored procedure in the same code but it only seems to work for one. They both work individually however. So either I have to reopen the connection or use 2 on the defined variables? Here is the code:
Dim rs As ADODB.Recordset
Dim cnSQL As ADODB.Connection
Dim sqlcommand As ADODB.Command, prm As Object, prm2 As Object
Set cnSQL = New ADODB.Connection
cnSQL.Open "Provider=SQLOLEDB; Data Source=bddc1didw1;Initial Catalog=Actuarial; Trusted_connection=Yes; Integrated Security='SSPI'"
Set sqlcommand = New ADODB.Command
sqlcommand.ActiveConnection = cnSQL
'groupdates
sqlcommand.CommandType = adCmdStoredProc
sqlcommand.CommandText = "GroupDate"
Set prm = sqlcommand.CreateParameter("GroupNumberEntry", adVarChar, adParamInput, 5)
Set prm2 = sqlcommand.CreateParameter("ValuationDateEntry", adDate, adParamInput)
sqlcommand.Parameters.Append prm
sqlcommand.Parameters.Append prm2
sqlcommand.Parameters("GroupNumberEntry").Value = "01132"
sqlcommand.Parameters("ValuationDateEntry").Value = "08-31-2019"
Set rs = New ADODB.Recordset
rs.CursorType = adOpenStatic
rs.LockType = adLockOptimistic
rs.Open sqlcommand
ActiveSheet.Range("a2").CopyFromRecordset rs
'GroupCommissions
sqlcommand.CommandType = adCmdStoredProc
sqlcommand.CommandText = "GroupCommissions"
Set prm = sqlcommand.CreateParameter("GroupNumberEntry", adVarChar, adParamInput, 5)
sqlcommand.Parameters.Append prm
sqlcommand.Parameters("GroupNumberEntry").Value = "01132"
Set rs = New ADODB.Recordset
rs.CursorType = adOpenStatic
rs.LockType = adLockOptimistic
rs.Open sqlcommand
ActiveSheet.Range("DB2").CopyFromRecordset rs
Try replacing that line with something like this:
Set prm = sqlcommand.CreateParameter("GroupNumberEntry", adVarChar, GroupNumberEntry, 255)
Set the field type and length according to how your proc is defined.
Your code looked OK to me so I copied it into Excel (2016...) and tried it. It gave me an error on that line but adding the additional parameter values to CreateParameter fixed the issue. shrug It shouldn't matter since those are optional parameters, unless there is something maybe at the provider level.
you can try just sending the SQL PROCEDURE straight through as a CALL function.
Take a look at this:
Public connDB As New ADODB.Connection
Public rs As New ADODB.Recordset
Public strSQL As String
Public strConnectionstring As String
Public strServer As String
Public strDBase As String
Public strUser As String
Public strPwd As String
Public PayrollDate As String
Sub WriteStoredProcedure()
PayrollDate = "2017/05/25"
Call ConnectDatabase
On Error GoTo errSP
strSQL = "EXEC spAgeRange '" & PayrollDate & "'"
connDB.Execute (strSQL)
Exit Sub
errSP:
MsgBox Err.Description
End Sub
Sub ConnectDatabase()
If connDB.State = 1 Then connDB.Close
On Error GoTo ErrConnect
strServer = "SERVERNAME" ‘The name or IP Address of the SQL Server
strDBase = "TestDB"
strUser = "" 'leave this blank for Windows authentication
strPwd = ""
If strPwd > "" Then
strConnectionstring = "DRIVER={SQL Server};Server=" & strServer & ";Database=" & strDBase & ";Uid=" & strUser & ";Pwd=" & strPwd & ";Connection Timeout=30;"
Else
strConnectionstring = "DRIVER={SQL Server};SERVER=" & strServer & ";Trusted_Connection=yes;DATABASE=" & strDBase 'Windows authentication
End If
connDB.ConnectionTimeout = 30
connDB.Open strConnectionstring
Exit Sub
ErrConnect:
MsgBox Err.Description
End Sub

Can't execute SQL Server stored procedure in Access module

In Access I created a form with Text1, List1, and Command1 elements.
The code for command button is:
Private Sub Command1_Click()
Dim con As ADODB.Connection
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset
Set con = New ADODB.Connection
Set cmd = New ADODB.Command
Set rs = New ADODB.Recordset
con.Open "Provider=sqloledb;Data Source=192.168.100.41,1433;Network Library=DBMSSOCN;Initial Catalog=xxx;User ID=xxx;Password=xxx;"
cmd.ActiveConnection = con
cmd.CommandTimeout = 0
cmd.Parameters.Append cmd.CreateParameter("#keyword", adVarChar, adParamInput, 100, Trim(Text1.Value))
cmd.CommandText = "stored_procedure"
Set rs = cmd.Execute(, , adCmdStoredProc)
If (rs.RecordCount <> 0) Then
Do While Not rs.EOF
Me.List1.AddItem (rs.Fields(0).Value & " | " & rs.Fields(1).Value & " | " & rs.Fields(2).Value)
rs.MoveNext
Loop
End If
rs.Close
Set rs = Nothing
Set cmd = Nothing
con.Close
Set con = Nothing
End Sub
When I try to run the code, nothing happens. No error. Seems like button is empty.
The SP works fine in SQL server.
The same button code, works fine in Excel form.
If I replace SP part with [rs.open "select * from table where keyword like.."] works fine
Thank you
You probably need to use a client side cursor, I would debug.print rs.RecordCount to check what it thinks are the returned records.
conn.cursorlocation=aduseclient

SQL Server Stored Procedure doesnt appear to be called

The syntax of my code in MS Access appears to be correct.
I can run the stored procedure manually in SQL and get the correct result.
When I try to call the stored procedure from MS Access using ADO nothing appears to happen; any help would be greatly appreciated.
Private Sub Combo13_LostFocus()
Dim P1 As Integer
P1 = Forms![Frm_Ws10a]![Frm_WS10b]![Combo13].Column(0)
Dim rs As ADODB.Recordset
Dim CN As ADODB.Connection
Dim cmd As ADODB.Command
Dim prm As ADODB.Parameter
Dim adstring As Variant
Set CN = New ADODB.Connection
CN.ConnectionString = "Driver=SQL
Server;Server=LDXFBHD013492 \SQLEXPRESS;Database=xxxx;Trusted_Connection=YES;"
CN.Open
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = CN
.CommandText = "dbo.usp_update_consequenceweighting"
.CommandType = adCmdStoredProc
.Parameters.Refresh
Set prm = .CreateParameter("#ITID", adInteger, adParamInput)
prm.Value = P1
End With
Set rs = cmd.Execute
Me.Recalc
Me.Refresh
Thanks in advance
You are missing the .parameters.append in your code below
With cmd
.ActiveConnection = CN
.CommandText = "dbo.usp_update_consequenceweighting"
.CommandType = adCmdStoredProc
.Parameters.Refresh
Set prm = .CreateParameter("#ITID", adInteger, adParamInput)
Try adding the parameter.append instead of setting it
With cmd
.ActiveConnection = CN
.CommandText = "dbo.usp_update_consequenceweighting"
.CommandType = adCmdStoredProc
.parameter.append .createparameter("#ITID", adInteger, adParamInput, 50, [Value or variable here])
.execute 1
End With

Receiving an Error " The object you entered is not a valid record set property" access 2013 assigning record set to a form

I am using Access 2013 to upgrade an old application with sql 2012 back end. I have several Stored Procedures with parameters which i need to call and assigned to forms and reports.
The issue i am having is that i get the error "7965" every time i try to assigned the returned record set to the form
i am using the open event of the form and the following code
Private Sub Form_Open(Cancel As Integer)
Dim cmd1 As ADODB.Command
Dim recs1 As New ADODB.Recordset
Dim prm1 As ADODB.Parameter
Dim prm2 As ADODB.Parameter
Dim prm3 As ADODB.Parameter
Set cnn = CreateObject("ADODB.Connection")
cnn.ConnectionString = "DRIVER={SQL Server Native Client 11.0};SERVER=192.168.0.12;DATABASE=SavingsPlusCorp;Trusted_Connection=yes;"
cnn.Open cnn.ConnectionString
Set cmd1 = New ADODB.Command
Set cmd1.ActiveConnection = cnn
cmd1.CommandText = "dbo.iNVENSOLDSp"
cmd1.CommandType = adCmdStoredProc
Set prm1 = cmd1.CreateParameter("#branchid", adInteger, adParamInput, 2)
cmd1.Parameters.Append prm1
Set prm2 = cmd1.CreateParameter(" #Beginning_Date", adDate, adParamInput)
cmd1.Parameters.Append prm2
Set prm3 = cmd1.CreateParameter(" #Ending_Date", adDate, adParamInput)
cmd1.Parameters.Append prm3
Set prm4 = cmd1.CreateParameter("#vENDORID", adInteger, adParamInput, 2)
cmd1.Parameters.Append prm4
Set prm5 = cmd1.CreateParameter("#catID", adInteger, adParamInput, 2)
cmd1.Parameters.Append prm5
prm1.Value = Form_ReportGenerator.Branches
prm2.Value = Form_ReportGenerator.Begin_Date
prm3.Value = Form_ReportGenerator.Ending_Date
prm4.Value = Form_ReportGenerator.Vendors
prm5.Value = Form_ReportGenerator.Category
Set recs1 = CreateObject("ADOdB.recordset")
recs1.CursorType = adOpenKeyset
recs1.CursorLocation = adUseClient
'Set recs1 = cmd1.Execute
'recs1.Open
Set Me.Recordset = cmd1.Execute
I have also tried
set me.Recordset= recs1
with the same results
please help
The solution in the the thread identified as a possible is almost identical to my attempt
In fact I used it to build my attempt
I used the command. Execute and assigned it to my form
Set me.RecordSet = cmd1.execute
It is this line that returns the error
Is their an issue with the provider I am using to connect
I don't understand why it is not working
Please help
I had this problem, spent hours looking for it... turned to be right under my nose:
A function that had work perfectly well, repopulating an Access combo box from Mysql backed, suddenly gave this message after I changed adUseClient to adUseServer for barely relevant reasons. Here's the code (with thanks to Author: Christian Coppes)
Public Function fnADOComboboxSetRS(cmb As String, strSQL As String, strCallingForm As String, Optional StrCnnstring As String)
On Error GoTo fnADOComboboxSetRS_Error
Dim sourceDB As New clsAdoDBHelper
Dim RS1 As New ADODB.Recordset
If Len(StrCnnstring & vbNullString) = 0 Then
sourceDB.Connect CnString
Else
sourceDB.Connect StrCnnstring
End If
Set RS1 = sourceDB.OpenRecordset(strSQL, adUseClient)
Set Application.Forms(strCallingForm).Controls(cmb).Recordset = RS1
fnADOComboboxSetRS_Exit:
If Not RS1 Is Nothing Then
If RS1.State = adStateOpen Then RS1.Close
Set RS1 = Nothing
End If
Exit Function
fnADOComboboxSetRS_Error:
Select Case Err
Case Else
'fnErr "modODBC->fnADOComboboxSetRS", True
Resume fnADOComboboxSetRS_Exit
End Select
End Function
You need to call the Open method of an ADO.Recordset object.
To demonstrate this, first create a simple stored procedure in SQL Server.
USE AdventureWorks2016CTP3;
GO
CREATE PROCEDURE dbo.up_TestPerson
AS
SELECT BusinessEntityID, FirstName, LastName
FROM Person.Person;
Then create a Microsoft Access form with this code behind.
Private Sub Form_Open(Cancel As Integer)
Dim cnn As New ADODB.Connection
cnn.ConnectionString = "DRIVER={SQL Server Native Client 11.0};SERVER=V-SQL16-R;DATABASE=AdventureWorks2016CTP3;Trusted_Connection=yes;"
cnn.Open
Dim cmd1 As New ADODB.Command
Set cmd1.ActiveConnection = cnn
cmd1.CommandText = "dbo.up_TestPerson"
cmd1.CommandType = adCmdStoredProc
Dim rst As New ADODB.Recordset
rst.Open cmd1, , adOpenKeyset, adLockPessimistic
Set Me.Recordset = rst
End Sub
Open the form, and it displays the data.
To demonstrate using a parameter, create a stored procedure like this. (Same as the first stored procedure, except it has a parameter and a WHERE clause.)
CREATE PROCEDURE dbo.up_TestPerson2
(
#PersonType nchar(2)
)
AS
SELECT BusinessEntityID, FirstName, LastName
FROM Person.Person
WHERE PersonType = #PersonType;
Create another Access form with this code behind. (Same as the first form, except for the block where we create and configure the parameter.)
Private Sub Form_Open(Cancel As Integer)
Dim cnn As New ADODB.Connection
cnn.ConnectionString = "DRIVER={SQL Server Native Client 11.0};SERVER=V-SQL16-R;DATABASE=AdventureWorks2016CTP3;Trusted_Connection=yes;"
cnn.Open
Dim cmd1 As New ADODB.Command
Set cmd1.ActiveConnection = cnn
cmd1.CommandText = "dbo.up_TestPerson2"
cmd1.CommandType = adCmdStoredProc
' This is new
Dim prm1 As ADODB.Parameter
Set prm1 = cmd1.CreateParameter("#PersonType", adWChar, adParamInput, 2)
cmd1.Parameters.Append prm1
prm1.Value = "EM"
Dim rst As New ADODB.Recordset
rst.Open cmd1, , adOpenKeyset, adLockPessimistic
Set Me.Recordset = rst
End Sub
Open the form and it displays records matching the parameter.

Bind Access form to the results from a Stored Procedure

I am trying to return the results of a stored procedure to a form. I have managed to iterate thru the results using an ADO recordset, but cannot bind the results to the form..
Here is the VBA code:
Private Sub RetrieveSiteInformation()
Dim cmd As New ADODB.Command
Dim cnn As New ADODB.Connection
Dim rs As ADODB.Recordset, f As ADODB.Field
With cnn
.Provider = "SQLOLEDB"
.ConnectionString =
"data source=UKFCSVR;initial catalog=ACACB;Trusted_Connection=Yes"
.Open
End With
Dim param1 As ADODB.Parameter
If Nz(txtSiteID_Search.Value, vbNullString) <> vbNullString Then
Set param1 = cmd.CreateParameter("#SiteID", adBigInt, adParamInput)
param1.Value = txtSiteID_Search.Value
cmd.Parameters.Append param1
End If
With cmd
.ActiveConnection = cnn
.CommandText = "spSiteInformation_Retrieve"
.CommandType = adCmdStoredProc
**' THIS FAILS**
Me.Recordset = .Execute
**' THIS LOOP WORKS FINE**
' Set rs = .Execute
' rs.MoveFirst
' For Each f In rs.Fields
' Debug.Print f.Name
' Next
' With rs
' Do While Not .EOF
' Debug.Print ![CompanyName] & " " & ![Postcode]
' .MoveNext
' Loop
' End With
End With
cnn.Close
End Sub
Okay, I have tested this example. It includes changes to suit my set-up which I have left in, rather than guessing at your set-up. Most of this is taken from http://support.microsoft.com/kb/281998/EN-US/
Dim cn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim param1 As New ADODB.Parameter
With cn
.Provider = "Microsoft.Access.OLEDB.10.0"
.Properties("Data Provider").Value = "SQLOLEDB"
.Properties("Data Source").Value = "Server"
.Properties("Integrated Security").Value = "SSPI"
.Properties("Initial Catalog").Value = "Test"
.Open
End With
txtSiteID_Search = 1
If Nz(txtSiteID_Search, vbNullString) <> vbNullString Then
Set param1 = cmd.CreateParameter("#SiteID", adBigInt, adParamInput)
param1.Value = txtSiteID_Search
cmd.Parameters.Append param1
End If
With cmd
.ActiveConnection = cn
.CommandText = "spSiteInformation_Retrieve"
.CommandType = adCmdStoredProc
Set Me.Recordset = .Execute
End With
Forget ADO. Create a passthru query in Access, with property ReturnsRecords = True.
Bind your form to that passthru query.
Using VBA, change the .SQL property of that QueryDef object, then open the form. You're done.
Set qry = CurrentDb.QueryDefs("myQryDef")
qry.SQL = "exec spMyStoredProc " & "'argument1'"
You need to use Set whenever you assign an object reference in VBA.
Change Me.Recordset = .Execute to Set Me.Recordset = .Execute.
Also, you probably need to open it with a supported cursor type. I don't think there's a way to change the cursor type if you use the Execute method on the Command object. You'll have to create the Recordset separately.
Set rs = New ADODB.Recordset
rs.Open cmd, , adOpenKeyset
Set Me.Recordset = rs

Resources