![](/img/trans.png)
[英]Delphi: “Parameter object is improperly defined. Inconsistent or incomplete information was provided.”
[英]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
我有运行该程序的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的任何值。) :
使用Parameters.Refresh
自动设置命令的参数集合时,可以手动覆盖任何VARCHAR(MAX)
输出参数大小的设置,使其小于2147483647:
cmd.Parameters.Item(Output_Variables(i).Name).Size = 2147483646
或者,将存储过程的VARCHAR
out参数设置为小于2147483647的大小:
@SP_Message VARCHAR(2147483646) = '' OUTPUT
或者,不要使用Parameters.Refresh
而是手动创建所有参数并将它们附加到命令的集合中。 您的输出参数将附加如下内容:
cmd.Parameters.Append cmd.CreateParameter(Output_Variables(i).Name, _ adVarChar, _ adParamInputOutput, _ 2147483646)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.