繁体   English   中英

运行时错误“ 3708”:参数对象定义不正确。 提供的信息不一致或不完整

[英]Run-time error '3708': Parameter Object is improperly defined. Inconsistent or incomplete information was provided

我试图使用VBA代码从Access窗体运行存储过程,但始终收到错误消息(“ 运行时错误'3708':参数对象定义不正确。提供的信息不一致或不完整 ”)。 有人可以帮助我找出我要去哪里。

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
  1. 我有运行该程序的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 

    那是代码。我要去哪里错了

首先,由于使用的是Parameters.Refresh ,因此您不想将参数附加到参数集合中。 相反,将值应用于输入参数时,应使用以下格式:

cmd.Parameters.Item(Input_Variables(i).Name).Value = Input_Variables(i).Value

您的VBA代码中注释了这样一行。 我认为这意味着您以前尝试过。 但是,您用单引号( ' )封装了Input_Variables(i).Value 你不应该这样做。 您只需要确保要传递的值与参数设置的类型相同即可。 注意: 在您的情况下,所有Input_Variables都是字符串,因此InsertProcedure函数仅适用于仅具有字符串类型参数的存储过程。

同样适用于您的输出参数。 但是,除非您实际上将它们同时用作输入和输出参数,否则您可能不需要或不想设置它们的值。

您的输出参数之一是VARCHAR(MAX)类型。 Parameters.Refresh调用很有可能将该参数的Size设置为2,147,483,647,这是VBA中Long类型的最大正值。 不幸的是,由于我承认的原因,我不完全了解,可以将adVarChar参数设置为的实际最大大小比该值小2(1,147,483,646)。 我最好的猜测是,无需过多研究,这涉及某种开销。 保留大小为2,147,483,647将导致您收到错误。


您有三个选项VARCHAR(MAX) VBA中的VARCHAR(MAX) ADO输出参数问题。 (对于以下所有选项,我使用值2147483646,但它可以是大于0且小于2147483647的任何值。)

  1. 使用Parameters.Refresh自动设置命令的参数集合时,可以手动覆盖任何VARCHAR(MAX)输出参数大小的设置,使其小于2147483647:

     cmd.Parameters.Item(Output_Variables(i).Name).Size = 2147483646 
  2. 或者,将存储过程的VARCHAR out参数设置为小于2147483647的大小:

     @SP_Message VARCHAR(2147483646) = '' OUTPUT 
  3. 或者,不要使用Parameters.Refresh而是手动创建所有参数并将它们附加到命令的集合中。 您的输出参数将附加如下内容:

     cmd.Parameters.Append cmd.CreateParameter(Output_Variables(i).Name, _ adVarChar, _ adParamInputOutput, _ 2147483646) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM