[英]Run-time error '3708': Parameter Object is improperly defined. Inconsistent or incomplete information was provided
I trying to run a stored procedure from an Access form using VBA code but I keep getting the error (" Run-time error '3708': Parameter Object is improperly defined. Inconsistent or incomplete information was provided "). 我试图使用VBA代码从Access窗体运行存储过程,但始终收到错误消息(“ 运行时错误'3708':参数对象定义不正确。提供的信息不一致或不完整 ”)。 Could someone help me figure out where I am going wrong.
有人可以帮助我找出我要去哪里。
. 。 1. I have a table called " CurrTbl " and a stored procedure called " ManageCurrency "
1.我有一个名为“CURRTBL”表和称为“ManageCurrency”存储过程
CREATE TABLE [dbo].[CurrTbl](
[CurrencyID] [int] IDENTITY(1,1) NOT NULL,
[CurrencyCountry] [varchar](250) NOT NULL,
[CurrencyName] [varchar](250) NOT NULL,
[ISOCODE] [varchar](3) NOT NULL,
[lg_user] [varchar](150) NULL,
CONSTRAINT [PK_CurrencyName] PRIMARY KEY CLUSTERED
(
[CurrencyID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [dbo].[CurrTbl] ADD CONSTRAINT [DF_CurrTbl_lg_user] DEFAULT (original_login()) FOR [lg_user]
GO
CREATE procedure [dbo].[ManageCurrency]
@CurCountry varchar(250),
@CurName varchar(250),
@ICode varchar(3),
@Flag smallint = 0 OUTPUT,
@SP_Message Varchar(MAX) = '' OUTPUT
AS
BEGIN
DECLARE @si AS BIGINT = 0;
If (ISNULL(@CurCountry,'') <> '' and ISNULL(@ICode,'') <> '')
BEGIN
merge dbo.CurrTbl as T
USING (Select @CurCountry AS CurrencyCountry, @CurName AS CurrencyName, @ICode as ISOCode) AS S
ON (T.CurrencyCountry = S.CurrencyCountry and T.ISOCode = S.ISOCode)
WHEN NOT MATCHED BY TARGET
THEN INSERT (CurrencyCountry,CurrencyName,ISOCode)
VALUES (@CurCountry,@CurName,@ICode)
WHEN MATCHED
THEN UPDATE SET T.CurrencyName = @CurName;
-- Getting the lastest scope identity of the last entry
SELECT @si = CurrencyID from dbo.CurrTbl where CurrencyID = SCOPE_IDENTITY();
END
If (ISNULL(@si,'')<> '') SET @SP_Message = 'Operation Sucessful'; Set @Flag = 1;
If (ISNULL(@si,'')= '') Set @SP_Message = 'Operation Not Sucessful'; Set @Flag = 0;
END
I have a VBA Code that runs the procedure 我有运行该程序的VBA代码
Public Type SP_Variable Name As String Value As String End Type Private Sub Command0_Click() Dim SQL_Var(3) As SP_Variable Dim Out_Var(2) As SP_Variable SQL_Var(1).Name = "@CurCountry" SQL_Var(1).Value = "KAMPALA" SQL_Var(2).Name = "@CurName" SQL_Var(2).Value = "KAMPALA SHILLING" SQL_Var(3).Name = "@ICode" SQL_Var(3).Value = "KSH" Out_Var(1).Name = "@Flag" Out_Var(1).Value = "" Out_Var(2).Name = "@SP_Message" Out_Var(2).Value = "" Call InsertProcedure("ManageCurrency", SQL_Var, 3, Out_Var, 2) End Sub Public Function InsertProcedure(ProcedureName As String, ByRef Input_Variables() As SP_Variable, InputVar As Integer, ByRef Output_Variables() As SP_Variable, OutputVar As Integer) As String Dim Conn As ADODB.Connection Dim cmd As ADODB.Command Dim rs As ADODB.Recordset Dim sConnect As String sConnect = "driver={sql server};server=Svr;Database=Data_DB;UID=user;PWD=password;" '' Establish connection. Set Conn = New ADODB.Connection Conn.ConnectionString = sConnect Conn.Open '' Open recordset. Set cmd = New ADODB.Command cmd.ActiveConnection = Conn cmd.CommandText = ProcedureName cmd.CommandType = adCmdStoredProc cmd.CommandTimeout = 0 cmd.Parameters.Refresh ''For i = 1 To InputVar ''cmd.Parameters(SP_Variables(i).Name).Value = SP_Variables(i).Value ''cmd.Parameters.Append cmd.CreateParameter(Input_Variables(i).Name, adVarChar, adParamInput, 350) ''cmd.Parameters.Item(Input_Variables(i).Name).Value = "'" & Input_Variables(i).Value & "'" cmd.Parameters.Append cmd.CreateParameter("@CurCountry", adVarChar, adParamInput, 250, Input_Variables(3).Value) cmd.Parameters.Append cmd.CreateParameter("@CurName", adVarChar, adParamInput, 250, Input_Variables(3).Value) cmd.Parameters.Append cmd.CreateParameter("@ICode", adVarChar, adParamInput, 3, Input_Variables(3).Value) ''Next i ''For i = 1 To OutputVar '' ''cmd.Parameters(SP_Variables(i).Name).Value = SP_Variables(i).Value '' cmd.Parameters.Append cmd.CreateParameter(Output_Variables(i).Name, adVarChar, adParamInputOutput, 2000, Output_Variables(i).Value) '' Next i Set rs = cmd.Execute SP_Message = cmd.Parameters("@SP_Message").Value SP_Flag = cmd.Parameters("@Flag").Value ' Process results from recordset, then close it. rs.Close Set rs = Nothing End Function
That is the code.. Where am I going wrong 那是代码。我要去哪里错了
First off, since you are using Parameters.Refresh
, you don't want to append your parameters to the parameter collection. 首先,由于使用的是
Parameters.Refresh
,因此您不想将参数附加到参数集合中。 Instead, you should be using the following format when applying values to your input parameters: 相反,将值应用于输入参数时,应使用以下格式:
cmd.Parameters.Item(Input_Variables(i).Name).Value = Input_Variables(i).Value
You had a line like this commented out in your VBA code. 您的VBA代码中注释了这样一行。 I assume this means you tried it previously.
我认为这意味着您以前尝试过。 However, you encapsulated your
Input_Variables(i).Value
with single quotes ( '
). 但是,您用单引号(
'
)封装了Input_Variables(i).Value
。 You shouldn't do this. 你不应该这样做。 You just need to make sure the value you are passing is of the same type that the parameter is set to.
您只需要确保要传递的值与参数设置的类型相同即可。 ( NOTE: In your case, all of your
Input_Variables
are strings, so your InsertProcedure
function will only work with stored procedures that have only string type parameters. ) ( 注意: 在您的情况下,所有
Input_Variables
都是字符串,因此InsertProcedure
函数仅适用于仅具有字符串类型参数的存储过程。 )
The same applies to your output parameters. 同样适用于您的输出参数。 However, you probably don't need or want to set their value unless you are actually using them as both an Input and Output parameter.
但是,除非您实际上将它们同时用作输入和输出参数,否则您可能不需要或不想设置它们的值。
One of your output parameters is of type VARCHAR(MAX)
. 您的输出参数之一是
VARCHAR(MAX)
类型。 The Parameters.Refresh
call is more than likely setting the Size
of that parameter to 2,147,483,647 which is the maximum positive value of a Long
type in VBA. Parameters.Refresh
调用很有可能将该参数的Size
设置为2,147,483,647,这是VBA中Long
类型的最大正值。 Unfortunately, and for reasons I admit I don't fully understand, the actual maximum size you can set an adVarChar
parameter to is 1 less than that (2,147,483,646). 不幸的是,由于我承认的原因,我不完全了解,可以将
adVarChar
参数设置为的实际最大大小比该值小2(1,147,483,646)。 My best guess without looking in to it too much is that some kind of overhead is involved. 我最好的猜测是,无需过多研究,这涉及某种开销。 Leaving the size at 2,147,483,647 will result in the error you are receiving.
保留大小为2,147,483,647将导致您收到错误。
You have three options for solving the VARCHAR(MAX)
ADO output parameter issue in VBA. 您有三个选项
VARCHAR(MAX)
VBA中的VARCHAR(MAX)
ADO输出参数问题。 (For all options below, I use the value 2147483646, but it can be any value greater than 0 and less than 2147483647.) : (对于以下所有选项,我使用值2147483646,但它可以是大于0且小于2147483647的任何值。) :
When using Parameters.Refresh
to automatically set up the parameter collection of your command, you can manually override the setup of any VARCHAR(MAX)
output parameter sizes to be something smaller than 2147483647: 使用
Parameters.Refresh
自动设置命令的参数集合时,可以手动覆盖任何VARCHAR(MAX)
输出参数大小的设置,使其小于2147483647:
cmd.Parameters.Item(Output_Variables(i).Name).Size = 2147483646
Or, set up your stored procedure's VARCHAR
out parameters with a size smaller than 2147483647: 或者,将存储过程的
VARCHAR
out参数设置为小于2147483647的大小:
@SP_Message VARCHAR(2147483646) = '' OUTPUT
Or, don't use Parameters.Refresh
and instead create all of your parameters manually and append them to the command's collection. 或者,不要使用
Parameters.Refresh
而是手动创建所有参数并将它们附加到命令的集合中。 Your output parameter would be appended something like this: 您的输出参数将附加如下内容:
cmd.Parameters.Append cmd.CreateParameter(Output_Variables(i).Name, _ adVarChar, _ adParamInputOutput, _ 2147483646)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.