How to execute Sybase function/stored procedure from MS-Access vba? - vba

I have a Access front end that has an ODBC connection titled fna to the Sybase back end on a server. I can easily reference the tables in the Sybase database but in the vba I need to be able to call stored procedures and functions that are in Sybase.
Function name is CalcStats.
Edit:
After reading through some of the links in the comment, I have gotten to the following code which seems to run but I can't figure out how to find the return value the function is providing.
Dim trash As String
Dim conn As ADODB.Connection
Dim cmd1 As ADODB.Command
Dim rs1 As Recordset
Set conn = New ADODB.Connection
conn.ConnectionString = "datasource=ODBC;DSN=fna"
conn.Open
Set cmd1 = New ADODB.Command
cmd1.ActiveConnection = conn
cmd1.CommandType = adCmdStoredProc
cmd1.CommandText = "CalcStats"
cmd1.Execute
Edit 2:
Finally figured out the output part. Thank you A.S.H for the links and Gord Thompson for the method for getting the connection string that for the ADODB that is needed.
So I can now create a connection, trigger the function and get the return value. However, now I'm working on the last part which is adding input parameters. I've added an input parameter to the function in sybase and saved it but I can't seem to pass an input value into the function on the Access side.
Dim trash As String
Dim conn As ADODB.Connection
Dim cmd1 As ADODB.Command
Set conn = New ADODB.Connection
conn.ConnectionString = "datasource=ODBC;DSN=fna"
conn.Open
Set cmd1 = New ADODB.Command
cmd1.ActiveConnection = conn
cmd1.CommandType = adCmdStoredProc
cmd1.CommandText = "CalcStats"
cmd1.Parameters.Append cmd1.CreateParameter("MeasurementClm", adInteger, adParamInput, , 3)
cmd1.Parameters.Append cmd1.CreateParameter("OutputValue1", adInteger, adParamReturnValue)
cmd1.Execute
trash = cmd1.Parameters.Item(0).Value
conn.Close

So the last problem I was having is that for whatever reason, I could declare an output parameter if there were no inputs but if there are inputs I had to remove the output parameter declaration. The Function output is in the parameters.item(0) position. Thanks to A.S.H and Gord Thompson for the links and suggestions. Here is the code I ended up with that is working now:
Dim trash As String
Dim conn As ADODB.Connection
Dim cmd1 As ADODB.Command
Dim rs1 As Recordset
Set conn = New ADODB.Connection
conn.ConnectionString = "datasource=ODBC;DSN=fna"
conn.Open
Set cmd1 = New ADODB.Command
cmd1.ActiveConnection = conn
cmd1.CommandType = adCmdStoredProc
cmd1.CommandText = "CalcStats"
cmd1.Parameters.Refresh
cmd1.Parameters.Append cmd1.CreateParameter("InputValue1", adInteger, adParamInput, , 3)
'cmd1.Parameters.Append cmd1.CreateParameter("OutputValue3", adInteger, adParamReturnValue)
cmd1.Execute
trash = cmd1.Parameters.Item(0).Value
conn.Close

Related

Insert Into Table from Excel via VB button to stored procedure with Variables

I have a simple table AMC_GW_TESTTABLE with two columns, name nvarchar(20) and phone nvarchar(12). I also have a simple stored procedure with two variables.
create procedure AMC_GW_TESTSP (#name nvarchar(20),
#phone nvarchar(12)) as
insert into AMC_GW_Testtable (name,phone)
values (#name, #Phone)
I have been able to get a button in Excel to create the command:
exec dbo.amc_gw_testsp 'fred' '620-555-1212'
But it does not execute it. I copy this to my SSMS exactly like it and execute it and it works fine. Any ideas?
VBA code
Sub Button1_Click()
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim connStr As String
Dim param As ADODB.Parameter
Dim param2 As ADODB.Parameter
connStr = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;" _
& "Initial Catalog=am_app);Data Source=bcu-sql-01"
Set conn = New ADODB.Connection
conn.ConnectionString = connStr
conn.Open
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = conn
.CommandType = adCmdStoredProc
.CommandText = "AMC_GW_TESTSP"
Set param = .CreateParameter("#name", adVarChar, adParamInput, 20, "Christopher")
.Parameters.Append param
Set param2 = .CreateParameter("#phone", adVarChar, adParamInput, 12, "0123456789")
.Parameters.Append param
.Execute
End With
conn.Close
Set cmd = Nothing
Set conn = Nothing
End Sub
I hope I did not scare you with a request for VBA Code
To give you an idea of what you should have:
Sub Button1_Click()
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim connStr As String
Dim param As ADODB.Parameter
Dim param2 As ADODB.Parameter
connStr = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;" & _
"Initial Catalog=dbname;Data Source=servername"
Set conn = New ADODB.Connection
conn.ConnectionString = connStr
conn.Open
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = conn
.CommandType = adCmdStoredProc
.CommandText = "AMC_GW_TESTSP"
Set param = .CreateParameter("#name", adVarChar, adParamInput, 20, "Christopher")
.Parameters.Append param
Set param2 = .CreateParameter("#phone", adVarChar, adParamInput, 12, "0123456789")
.Parameters.Append param
.Execute
End With
conn.Close
Set cmd = Nothing
Set conn = Nothing
End Sub
Things that you will have to change. Firstly the connection string (connStr). You will need to provide database name in place of dbname and server in place of servername. Also this string is assuming that you are using Windows Authentication for your SQL Server. If not you need to remove Integrated Security=SSPI; and in its place supply User ID=myUser;Password=myPassword;.
Next you will notice that the last parameter in the .CreateParameter function is a fixed string ("Christopher" and "0123456789"). In your case, they should be variables taken from cells in the spreadsheet. Please, please make sure that these strings do not contain ";" before trying to Execute.
I hope this helps, but feel free to contact me, if anything is less than clear!
PS You will need to make sure under Tools References, that you have the highest version of Microsoft ActiveX Data Objects Library checked (mine is 6.1, but anything 2.0 or higher definitely works).

Derive parameters of a stored procedure in VBA

I've tried searching a lot of places and can't quite find what I'm looking for.
I want to write a sub routine in vba that will tell me the parameters of a stored procedure stored on SQL Server.
I know how to execute a stored proc with parameters from excel vba. And I have written a stored proc that takes a stored proc name and returns the parameters. So I could use this. But I thought maybe there is a better way that I don't know about. I found a SQLCommandBuilder Class for VB that would be perfect but I need it in VBA. Is this available in VBA and I just don't know where to activate it?
Thanks
**Additional information: After the helpful comments below I am getting closer to what I am aiming to achieve.
I want to be able to pass any stored procedure into my subroutine and it will be able to figure out how many parameters it needs and what they will be
Here is my code so far
Private Sub execStoredProcedureWithParameters(strServer As String,
strDatabase As String, strSchema As String, strUSPName As String)
'Declare variables
Dim cmd As ADODB.Command
Dim conn As ADODB.Connection
Dim prm As ADODB.Parameter
Dim rs As ADODB.Recordset
Dim intParamCount As Integer
'Open database connection
Set conn = New ADODB.Connection
conn.ConnectionString = "Provider=sqloledb;Data Source=" + strServer + ";Initial Catalog=" + strDatabase + ";Integrated Security=SSPI;"
conn.CommandTimeout = 0
'Here's where the connection is opened.
conn.Open
'This can be very handy to help debug!
'Debug.Print conn.ConnectionString
Set cmd = New ADODB.Command
With cmd
.CommandText = strSchema + "." + strUSPName
.CommandType = adCmdStoredProc
.ActiveConnection = conn
.Parameters.Refresh
For intParamCount = 0 To .Parameters.Count - 1
Debug.Print .Parameters(intParamCount).Name, .Parameters(intParamCount).Type, .Parameters(intParamCounti).Size, .Parameters(intParamCount).Attributes, .Parameters(intParamCount).NumericScale
' Set prm = cmd.CreateParameter(.Parameters(i).Name, adVarChar, adParamInput, 255)
' cmd.Parameters.Append prm
' cmd.Parameters(.Parameters(i).Name).Value = "DBName"
Next
End With
Set rs = New ADODB.Recordset
'Execute the Stored Procedure
Set rs = cmd.Execute
'Populate the sheet with the data from the recordset
Sheet1.Range("RecordSet").CopyFromRecordset rs
'Cleanup
rs.Close
Set rs = Nothing
conn.Close
Set conn = Nothing
End Sub
Concerning the parameters. Is there a way to convert the DataTypeEnum from the value to the constant. So the type is currently coming through as 202 for the first parameter which I would set to adVarWChar according to this table
https://learn.microsoft.com/en-us/sql/ado/reference/ado-api/datatypeenum
You can do this with ADODB, add a reference to Microsoft ActiveX Data Objects then you can:
With New ADODB.Command
Set .ActiveConnection = myAdoDbConnection
.CommandText = "[dbo].[usp_XXX]"
.CommandType = adCmdStoredProc
.Parameters.Refresh
For i = 0 To .Parameters.Count - 1
Debug.Print .Parameters(i).Name, .Parameters(i).Type, .Parameters(i).Direction
Next
End With
There should be a necessity requiring this as it requires a round trip to the server.

Excel VBA executing SQL Server stored procedure - result set throwing error 3704

I am trying to execute a SQL Server stored procedure from Excel VBA. The procedure returns rows into a result set object. However, while running the code, it throws an error:
3704 Operation is not allowed when the object is closed
Note:
There is no problem with the database connection because Select query running on the same connection object are working fine.
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim cmd As ADODB.Command
Dim prm As ADODB.Parameter
Dim rst As New ADODB.Recordset
Set cn = New ADODB.Connection
Set cmd = New ADODB.Command
ThisWorkbook.initialize
cn.Provider = "sqloledb"
cn.Properties("Data Source").Value = ThisWorkbook.server
cn.Properties("Initial Catalog").Value = ThisWorkbook.db
cn.Properties("User ID").Value = "xxxxx"
cn.Properties("Password").Value = "xxxxx"
cn.Open
Set cmd = New ADODB.Command
cmd.CommandText = "Generate_KPI_Process_Quality_Check_RunTime"
cmd.CommandType = adCmdStoredProc
cmd.ActiveConnection = cn
Set prm = cmd.CreateParameter("#currentMonth", adChar, adParamInput, 255, cmb_month.Value)
cmd.Parameters.Append prm
Set prm = cmd.CreateParameter("#center", adChar, adParamInput, 255, cmb_center.Value)
cmd.Parameters.Append prm
rst.CursorType = adOpenStatic
rst.CursorLocation = adUseClient
rst.CursorLocation = adUseServer
rst.LockType = adLockOptimistic
rst.Open cmd
If (rst.BOF And rst.EOF) Then
'Some Code
End If
Put
SET NOCOUNT ON
in the stored procedure -- this will prevent output text generation like "1 record(s) updated".
You have to provide more parameters for the Open method of Recordset Object
try rst.Open cmd, cn
Use the Set keyword to assign the object:
Set cmd.ActiveConnection = cn
otherwise, the default property of the Connection object (which happen to be the connection string) will be assigned in lieu of the Connection object itself.
Just put another recordset that will contain resultsets
Dim rst1 As New ADODB.Recordset
SET rst1=rst.NextRecordset 'this will return the first resultset
If rst1.BOF or rst1.EOF Then...
'some code
End If

Running stored procedure from Excel

I am trying to run a stored procedure from Excel. I know how to do it without using dynamic dates but I need the date range to be dynamic.
Sub TestStoredProcedure()
Dim CServer As String
Dim CDatabase As String
Dim CLogon As String
Dim CPass As String
Dim StartDate As Date
Dim EndDate As Date
Dim TStartDate As String
Dim TEndDate As String
CServer = "111111" ' Your server name here
CDatabase = "111111" ' Your database name here
CLogon = "11111111" ' your logon here
CPass = "111111" ' your password here
Dim Cmd1 As New ADODB.Command
Dim rs As New ADODB.Recordset
Dim intTemp As Integer
Set Cmd1 = New ADODB.Command
Cmd1.ActiveConnection = cn
Cmd1.CommandText = "callstatisticsbyQ"
Cmd1.CommandType = adCmdStoredProc
Cmd1.Parameters.Refresh
Cmd1.Parameters(0).Value = Worksheets("Sheet2").Range("A1")
Cmd1.Parameters(1).Value = Worksheets("Sheet2").Range("A2")
Cmd1.Parameters(2).Value = Worksheets("Sheet2").Range("A3")
Set rs = Cmd1.Execute()
rs.Open Cmd1
Worksheets("Procedure Export").Range("A1").CopyFromRecordset rs
Call DumpSP("prcGetData", "", "", Worksheets("Procedure Export").Range("A1"))
End Sub
I get an error saying something about user defined type not defined.
To use ADO you click Tools->references in the VBA IDE & tick "Microsoft ActiveX Data Objects" - preferably the highest version thereof.
Additionally you use cn as the connection but its not defined in that sub (assuming its not global) & you will may need to Set Cmd1.ActiveConnection = cn.
Also take a look at this, it defines the input (adParaminput) paramaters in advance rather than using .Refresh which is pretty inefficient (takes a trip to the server)
Update for example:
rem for create procedure callstatisticsbyQ (#i int, #c varchar(10)) as select 1234;
Dim cn As ADODB.Connection
Dim Cmd1 As ADODB.Command
Dim rs As ADODB.Recordset
Set cn = New ADODB.Connection
Set Cmd1 = New ADODB.Command
Set Cmd1 = New ADODB.Command
cn.Open "Provider=SQLNCLI10;Server=1.2.3.4;Database=x;Uid=x; Pwd=x;"
Set Cmd1.ActiveConnection = cn
Cmd1.CommandText = "callstatisticsbyQ"
Cmd1.CommandType = adCmdStoredProc
Cmd1.Parameters.Append Cmd1.CreateParameter("p1", adInteger, adParamInput, , Worksheets("Sheet2").Range("A1"))
Cmd1.Parameters.Append Cmd1.CreateParameter("p2", adVarChar, adParamInput, 20, Worksheets("Sheet2").Range("A2"))
Set rs = Cmd1.Execute()
MsgBox rs(0)
rs.Close
cn.Close

How to call stored procedure in SQL Server from Excel (Windows Authentication)?

What is the syntax to call stored procedure in SQL Server from Excel (VBA) using windows authentication?
'Remember to reference Microsoft ActiveX Data Objects via Tools - References
Dim strConn As String
Dim conn As New Connection
Dim cmd As New ADODB.Command
Dim rs As New Recordset
strConn = "DRIVER=SQL Server;SERVER=ServerName;DATABASE=DBname"
conn.ConnectionString = strConn
conn.Open
cmd.ActiveConnection = conn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "SPName"
cmd.Parameters.Refresh 'requires a trip to server / can add parameters manually using cmd.Parameters.Append
cmd.Parameters("#Param1").Value = ""
Set rs = cmd.Execute
If Not rs.EOF Then
'your code here
End If
conn.Close
Set rs = Nothing