I would appreciate any help on this problem that has me stumped:
I am attempting to execute a SQL Server 2008 stored procedure from Access 365 VBA and keep faulting out with "Multiple-step OLE DB operation generated errors".
This fault began when I changed a column in the target table from int datatype to decimal(3,1). (I now need to be able to store a single digit to the right of the decimal).
For troubleshooting/ testing, I stripped the stored procedure down to update this column only. (OCR_Freq is the update column, OcrxId is the record id).
I have verified/tried:
1) The table column is set to decimal(3,1).
2) The data type in the stored procedure variable is decimal(3,1).
3) The stored procedure executes without issue from SQL Server
Management Studio.
4) Changing the column datatype to decimal(18,4) had no effect.
4) The vba code below executes without issue if the DataType is
adInteger.
5) I use this code to execute a number of other stored procedures
without issue.
'VBA CODE:
Dim Comm As ADODB.Command
Dim lngRecordsAffected As Long
Dim param1 As New ADODB.Parameter
Dim param2 As New ADODB.Parameter
'************************************************
Dim ocrxid As Long
Dim OCR_Freq As Variant
Dim x As Single
'testing the formatting
x = 7.2 'doesn't work
'OCR_Freq = Round(x, 1) 'doesn't work
'OCR_Freq = CDec(x) 'doesn't work
'OCR_Freq = Round(OCR_Freq, 1) 'doesn't work
OCR_Freq = CDec(Format(x, "00.0")) 'doesn't work
'connection stuff
If con.State = adStateClosed Then
con.ConnectionString = conConnection
con.Open
End If
Set Comm = New ADODB.Command
With Comm
.ActiveConnection = con
.CommandType = adCmdStoredProc
.CommandText = "up_EOCR_TEST"
'--- ADD PARAMETERS --------------------------------
'OCR_Freq decimal(3,1)
Set param1 = Comm.CreateParameter("#OCR_Freq", adDecimal,
adParamInput, , OCR_Freq)
Comm.Parameters.Append param1
'test record id
Set param2 = Comm.CreateParameter("#OcrxId", adInteger,
adParamInput, , 8053)
Comm.Parameters.Append param2
.Execute lngRecordsAffected
End With
'END VBA CODE
//SQL Stored Procedure:
#OCR_Freq decimal(3,1) = null,
#OcrxId int = null
as
begin
UPDATE dbo.OCRX SET OCR_Freq=#OCR_Freq WHERE OCR_ID=#OcrxId;
END
The error I am getting is "Multiple-step OLE DB operation generated errors"
The above leads me to conclude that I am not properly "preparing" the value in vba for the stored procedure execution- adDecimal is not happy with my variable...
but I am at loss as how to move forward. Any help would be appreciated.
Well, the solution was staring me in the face- I forgot to set the NumericScale and precision on param1 before appending it:
'VBA CODE CORRECTED:
Dim Comm As ADODB.Command
Dim lngRecordsAffected As Long
Dim param1 As New ADODB.Parameter
Dim param2 As New ADODB.Parameter
'************************************************
Dim ocrxid As Long
Dim OCR_Freq As Variant
Dim x As Single
'testing the formatting
x = 7.5
OCR_Freq = x
'connection stuff
If con.State = adStateClosed Then
con.ConnectionString = conConnection
con.Open
End If
Set Comm = New ADODB.Command
With Comm
.ActiveConnection = con
.CommandType = adCmdStoredProc
.CommandText = "up_EOCR_TEST"
'--- ADD PARAMETERS ---------------------------------------------------
'OCR_Freq decimal(3,1)
Set param1 = Comm.CreateParameter("#OCR_Freq", adDecimal, adParamInput, ,
OCR_Freq)
param1.NumericScale = 1
param1.Precision = 3
Comm.Parameters.Append param1
Set param2 = Comm.CreateParameter("#OcrxId", adInteger, adParamInput, ,
8053)
Comm.Parameters.Append param2
.Execute lngRecordsAffected
End With
Related
Seem to be getting unexpected white space when calling the stored procedure from VBA in Excel using ADODB object. The issue does not occur when running the procedure from SQL Server Management Studio.
exec usp_testloginalert '2015-11-29 00:00:00','2015-11-30 00:00:00',N'screen'
UPDATE
Code from vba
Function querylogs(ByVal todate As Date, ByVal fromdate As Date, ByVal desc As String)
Dim cn As ADODB.Connection
Dim cmdProd As ADODB.command
Dim prs As New ADODB.Recordset
sQuery = "usp_testloginalert"
Set cn = New ADODB.Connection
With cn
.Provider = "SQLOLEDB"
sConnection = "dbconn"
.ConnectionString = sConnection
.ConnectionTimeout = 1000
.CommandTimeout = 1000
End With
cn.Open sConnection
Set cmdProd = New ADODB.command
With cmdProd
.ActiveConnection = cn
.CommandType = adCmdStoredProc
.CommandText = "usp_testloginalert"
.CommandTimeout = 1000
End With
Dim prmFromDate As ADODB.Parameter
Set prmFromDate = cmdProd.CreateParameter("#FromDate", adDBDate,adParamInput)
prmFromDate.Value = fromdate
cmdProd.Parameters.Append prmFromDate
Dim prmToDate As ADODB.Parameter
Set prmToDate = cmdProd.CreateParameter("#ToDate", adDBDate, adParamInput)
prmToDate.Value = todate
cmdProd.Parameters.Append prmToDate
Dim prmDescritpion As ADODB.Parameter
cmdProd.Parameters.Append cmdProd.CreateParameter("Descritpion",adBSTR,adParamInput, 100, desc)
Set prs = New Recordset
prs.CursorLocation = adUseClient
prs.Open cmdProd.Execute
Application.EnableCancelKey = True
cn.Close
Set querylogs = prs
End Function
Hard to answer when we not see code of your procedure, but I can suggest you to use LTRIM and RTRIM to remove leading/trailing blanks.
In following: LTRIM(RTRIM( /* character_xpression */ ))
UPDATE
If It's not SQL issue, try to check for related posts:
Remove leading or trailing spaces in an entire column of data
Delete blanks from start and end of a string in vba
http://www.excelitems.com/2009/03/remove-extra-spaces-from-cell-value.html
issues resolved, set the parameter length to the length of the variable passed.
Dim lendesc As Integer
lendesc = Len(desc) + 1
Dim prmDescritpion As ADODB.Parameter
cmdProd.Parameters.Append cmdProd.CreateParameter("Descritpion", adBSTR,adParamInput, lendesc, desc)
I am using MS Access VBA to call a stored procedure with paramters passed from Access. I am having issues passing my date variables to the SQL Server Stored procedure:
VBA:
Dim zsql, asql, bsql, gsql As String
Dim searchDeal, searchReviewed As String
Dim searchDate, searchFile As Date
Dim searchType As String
Dim user As String
Dim qdfNew As DAO.QueryDef
Dim myRecordset6 As DAO.Recordset
Dim myDatabase6 As DAO.Database
Dim mycheckRs As DAO.Recordset
DoCmd.SetWarnings False
searchDeal = Me.cboDeal.Value
searchDate = Me.cboStDate.Value
searchFile = Me.cboFile.Value
user = GetUser()
Dim dbconn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim rs As New ADODB.Recordset
Dim param As New ADODB.Parameter
'' Connect to Data Source - Securities DB - SQL Server
Set dbconn = New ADODB.Connection
dbconn.ConnectionString = "driver=SQL Server;server=R7SQL1;database=SecuritiesDB;trusted_connection=YES"
dbconn.Open dbconn.ConnectionString
Set cmd = New ADODB.Command
cmd.ActiveConnection = dbconn
'' Set CommandText equal to the stored procedure name (spStatementCheck)
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "spAppendActivity"
''cmd.NamedParameters = True 'paramStatementCheck'
cmd.Parameters.Append _
cmd.CreateParameter("#SPstrNGN", adVarChar, adParamInput, 25, searchDeal)
cmd.Parameters.Append _
cmd.CreateParameter("#SPuser", adVarChar, adParamInput, 100, user)
cmd.Parameters.Append _
cmd.CreateParameter("#SPdDateActivity", adDBTimeStamp, adParamInput, 10, searchDate) <--ISSUE
cmd.Parameters.Append _
cmd.CreateParameter("#SPdDateFile", adDBTimeStamp, adParamInput, 10, searchFile) <--ISSUE
--Date format that I am passing should be MM/DD/YYYY
rs.CursorType = adOpenDynamic
rs.CursorLocation = adUseClient
rs.LockType = adLockOptimistic
rs.Open cmd
SQL:
ALTER PROCEDURE [dbo].[spAppendActivity]
#SPsearchDeal as nvarchar(25),
#SPsearchDate as datetime,
#SPsearchFile as datetime,
#SPuser as nvarchar(100)
AS
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
delete from tbl_Activity_Losses;
INSERT into tbl_Activity_Losses ([Date], NGN_Short, FileDate)
Select [Date], NGN_Short, Filedate
from tbl_Master_Rec
where tbl_Master_Rec.[Date] = #SPsearchDate <--Conversion Issue
and tbl_Master_Rec.FileDate = #SPsearchFile <--Conversion Issue
and tbl_Master_Rec.NGN_Short like '%' + #SPsearchDeal + '%'
I get the following error message when the Date is passed using the adDBTimeStamp "[Microsoft][ODBC SQL Server Driver] Conversion failed when converting date and/or time from character string."
I have also tried passing the date as adDBDate and get the error "[Microsoft][ODBC SQL Server Driver] Optional Feature Not Implemented. "
Please let me know if you need more information on the issue I am having
Please note that you will need to construct the datetime string in this format:
adDBDate
Indicates a date value (yyyymmdd) (DBTYPE_DBDATE).
adDBTimeStamp
Indicates a date/time stamp (yyyymmddhhmmss plus a fraction in billionths) (DBTYPE_DBTIMESTAMP).
adDBDate and adDBTimeStamp
Currently I pass the date parameter as varchar and convert because I got errors with passing a date parameter. I still get errors but its a conversion parameter.
Sub GetPositions() 'xdate As Date
Dim sSQL As String
Dim rs As ADODB.Recordset
Dim cn As ADODB.Connection
Dim cmd As ADODB.Command
Dim prm As ADODB.Parameter
Set cmd = New ADODB.Command
Set prm = New ADODB.Parameter
Sheets("Positions").Select
Range("a2:bb999999").ClearContents
Set cn = New ADODB.Connection
cn.CommandTimeout = 300000
cn.Open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=GlobalR;Data Source=SWP"
Dim d As Date
d = "2013/12/03"
cmd.ActiveConnection = cn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "Get9599Delta"
cmd.NamedParameters = True
Set prm = cmd.CreateParameter("#date", adVarChar, adParamInput, 12)
cmd.Parameters.Append prm
cmd.Parameters("#date").Value = "'12/3/2013'"
Set rs = New ADODB.Recordset
rs.Open cmd.Execute ''''I AM GETTING AN ERROR ON THIS LINE THAT READS
''''''''''' CONVERSION FAILED WHEN CONVERTING DATETIME TO CHARACTER STRING
Cells(2, 1).CopyFromRecordset rs
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
End Sub
here is my stored proc
alter PROC Get9599Delta (#date varchar(12))
AS
DECLARE #d DATETIME
SET #d = CONVERT(DateTime, #date, 104) --convert the varchar to a date
Any idea why I am having this conversion issue?
I'm using Excel 2016 MSO (16.0.8730.2175) 64-bit and my "VBAProject" is referencing "Microsoft ActiveX Data Objects 6.1 Library". I'm running SQL Server Express (64-bit) version 11.0.3156.0 (2012).
My SQL Server database stored procedure has a date parameter with a datetime data type. The stored procedure does not contain SET NOCOUNT ON.
Here's (an edited version of) my code:
Sub ExecuteStoredProcedure(date_ As Date)
Dim connection_ As New ADODB.Connection
connection_.Open "Provider=SQLOLEDB;Data Source=.\SQLEXPRESS;Initial Catalog=not_my_real_database_name;Integrated Security=SSPI"
Dim command_ As New ADODB.Command
With command_
.ActiveConnection = connection_
.CommandType = adCmdStoredProc
.CommandText = "dbo.NotMyRealProcedureName"
.Parameters.Append .CreateParameter("#Date", adDBDate, adParamInput, , date_)
.Execute
End With
End Sub
If you're having similar problems, try commenting or removing all of the code after the connection_.Open ... call. I definitely had problems because of the connection string passed to that call and the error info shown by VBA is so minimal that it was not immediately obvious that my problem wasn't related to the date parameter in my VBA code.
The problem was solved by putting SET NOCOUNT ON at the top of my stored procedure!
try this:
.Parameters.Append .CreateParameter("#date", adDate, adParamInput, , )
# is optional
msdn ( command.CreateParameter (Name, Type, Direction, Size, Value) )
and type of parameter adDBTimeStamp
Hi
I am trying to use a stored procedure in WORD VBA to retrieve some addresses using a stored procedure to populate a list field.
Private Sub txtCpny_AfterUpdate()
Dim rst As ADODB.Recordset
Dim cmd As ADODB.Command
Dim param1 As ADODB.Parameter
Dim param2 As ADODB.Parameter
Dim strCpny As String
strCpny = GetSearchString(Me.txtCpny) 'ie %Name%
Set cmd = CreateObject("ADODB.Command")
With cmd
.ActiveConnection = mcn
.CommandText = "LISTPARTNER_NAME"
.CommandType = adCmdStoredProc
Set param1 = .CreateParameter("RCT1", adInteger, adParamInputOutput, , Null)
Set param2 = .CreateParameter("firmaName", adVarChar, adParamInput, 50, strCpny)
.Parameters.Append param1
.Parameters.Append param2
Set rst = .Execute
End With
...Using the recordset here
rst.Close
Set param1 = Nothing
Set param2 = Nothing
Set cmd = Nothing
End Sub
The Stored Procedure looks as follows: The SQL should result in a recordset holding the matching Companies.
PROCEDURE LISTPARTNER_NAME (
firmaName IN VARCHAR2 DEFAULT NULL,
RCT1 IN OUT GLOBALPKG.RCT1
)
AS
BEGIN
OPEN RCT1 FOR
SELECT
...
FROM
...
WHERE
KNAG.NAME_ORG LIKE LISTPARTNER_NAME.firmaName
...
END LISTPARTNER_NAME
When the command is executed VB throws a RunTime Error
ORA-06550: Line 1, column 13:
PLS-00306: wrong number or types of arguments in call to
'LISTPARTNER_NAME'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
In my opinion the I am doing something wrong wit the parameters. Ihave been trying various versions of setting the parameters with no luck
Any Clues?
Thanks
have a look at this thread, it may be of assistance
http://forums.oracle.com/forums/thread.jspa?threadID=360922
The only other thing I could suggest would be switching the order of the parameters (so they are in the same order -- I know ODP defaults to order but I am unsure of ADODB)
I have been successfully using this code in Access:
Function runAdo(sql As String, usr As String, pwd As String)
'by Patrick Honorez - www.idevlop.com ----- 09-nov-2012
'Purpose : run Oracle proc using ADO connection
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Set cn = New ADODB.Connection
cn.Open GetPersonalizedConnectStringADO(usr, pwd)
Set rs = New ADODB.Recordset
rs.Open sql, cn, adOpenStatic, adLockReadOnly
cn.Close
End Function
I rarely use ADO from Access, since I find DAO simpler to use, but in this case I had to execute some Oracle procs requiring a different UID, and creating a new DAO Querydef specifying different UID and PWD, did not work, perhaps due to the fact that Access keeps a cache of connections.
So I decided to use ADO for the second "user" and it works like a charm.
I have a SQL Server 2008 stored procedure that updates values in a table. I would like to have the stored procedure return an integer value indicating that the update was successful (return 0) or not (returns error number). What would be the best way to accomplish this via ADO and VBA? Here some of my code in simplified form that performs the update ... I am just not sure how to get back the return value of the stored procedure
Public Function DoUpdate(employeeID as integer, firstName as string, lastname as string) as integer
Dim cnn As ADODB.Connection
Dim cmd As ADODB.Command
Dim activeConnectionString As String
activeConnectionString = GetActiveConnectionString()
Set cnn = New ADODB.Connection
cnn.ConnectionString = activeConnectionString
cnn.CursorLocation = adUseClient
cnn.Open
Set cmd = New ADODB.Command
cmd.ActiveConnection = cnn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "uspUpdateEmployeeName"
cmd.NamedParameters = True
cmd.Parameters("#EmployeeID").Value = employeeID
cmd.Parameters("#FirstName").Value = firstName
cmd.Parameters("#LastName").Value = lastName
cmd.Execute
'Unsure of how to get back return value here
'DoUpdate = returnValue
Set cnn = Nothing
End Function
Note: The return_value must be the first parameter!
Order matters.
I was getting errors stating that my query "had too many arguments" when I had specified my return_value parameter last, instead of first.
The parameters' ordering was the cause of my error.
If you use
Dim lngRecs As Long
cmd.Execute lngRecs
lngRecs should contain records affected.
I seem to remember that you need to supply an extra parameter with the type 'adParamReturnValue' like this:
Dim lRetVal as Long
Set cmd = New ADODB.Command
cmd.Parameters.Append .CreateParameter("returnvalue", adInteger, adParamReturnValue)
cmd.Execute
'Now check the return value of the procedure
lRetVal = cmd.Parameters("returnvalue")
If lRetVal > 0 then
Several ways are possible to get values back using VBA:
Recordset
Count of records affected (only for Insert/Update/Delete otherwise -1)
Output parameter
Return value
My code demonstrates all four. Here is a stored procedure that returns a value:
Create PROCEDURE CheckExpedite
#InputX varchar(10),
#InputY int,
#HasExpedite int out
AS
BEGIN
Select #HasExpedite = 9 from <Table>
where Column2 = #InputX and Column3 = #InputY
If #HasExpedite = 9
Return 2
Else
Return 3
End
Here is the sub I use in Excel VBA. You'll need reference to Microsoft ActiveX Data Objects 2.8 Library.
Sub CheckValue()
Dim InputX As String: InputX = "6000"
Dim InputY As Integer: InputY = 2014
'open connnection
Dim ACon As New Connection
'ACon.Open ("Provider=SQLOLEDB;Data Source=<SqlServer>;" & _
' "Initial Catalog=<Table>;Integrated Security=SSPI")
'set command
Dim ACmd As New Command
Set ACmd.ActiveConnection = ACon
ACmd.CommandText = "CheckExpedite"
ACmd.CommandType = adCmdStoredProc
'Return value must be first parameter else you'll get error from too many parameters
'Procedure or function "Name" has too many arguments specified.
ACmd.Parameters.Append ACmd.CreateParameter("ReturnValue", adInteger, adParamReturnValue)
ACmd.Parameters.Append ACmd.CreateParameter("InputX", adVarChar, adParamInput, 10, InputX)
ACmd.Parameters.Append ACmd.CreateParameter("InputY", adInteger, adParamInput, 6, InputY)
ACmd.Parameters.Append ACmd.CreateParameter("HasExpedite", adInteger, adParamOutput)
Dim RS As Recordset
Dim RecordsAffected As Long
'execute query that returns value
Call ACmd.Execute(RecordsAffected:=RecordsAffected, Options:=adExecuteNoRecords)
'execute query that returns recordset
'Set RS = ACmd.Execute(RecordsAffected:=RecordsAffected)
'get records affected, return value and output parameter
Debug.Print "Records affected: " & RecordsAffected
Debug.Print "Return value: " & ACmd.Parameters("ReturnValue")
Debug.Print "Output param: " & ACmd.Parameters("HasExpedite")
'use record set here
'...
'close
If Not RS Is Nothing Then RS.Close
ACon.Close
End Sub