无法将参数发送到 MySQL 存储过程窗口窗体

Posted

技术标签:

【中文标题】无法将参数发送到 MySQL 存储过程窗口窗体【英文标题】:Can't send parameters to a MySQL Stored Procedure windows form 【发布时间】:2021-10-31 02:14:27 【问题描述】:

我正在尝试使用 vb.net 中的类在 mariadb 存储过程中插入数据,但我不断收到错误消息,提示 PROCEDURE 的参数数量不正确 ... 预期为 12。但 0 什么这是什么意思?我该如何解决这个错误?我在我的代码中遗漏了什么吗?

注意:数据库连接没有问题

    Try
        Dim arrParameter, arrParamName
        Dim sParamName As String
        Dim sDataValue As String
        Dim sDataTypes As String
        Dim lCtr As Long
        Dim param(lParameter) As mysqlParameter
        Dim cmd As New MySqlCommand()
        cmd.Connection = conn
        cmd.CommandText = sStoreProcName
        cmd.CommandType = CommandType.StoredProcedure
        InsertUpdateData = False
        cmd = New MySqlCommand(sStoreProcName, conn)
        arrParameter = Split(sParameterList, "|", , vbTextCompare)
        If Not Trim(sParameterList) = "" Then
            If UBound(arrParameter) >= 0 And IsArray(arrParameter) Then
                For lCtr = 0 To UBound(arrParameter)
                    arrParamName = Split(arrParameter(lCtr), "$", , vbTextCompare)
                    sParamName = arrParamName(0)
                    sDataTypes = arrParamName(1)
                    sDataValue = arrParamName(2)
                    If sDataTypes = "string" Then
                        cmd.Parameters.Add(sParamName, MySqlDbType.VarChar, 200, sDataValue)
                        cmd.Parameters(sParamName).Direction = ParameterDirection.Input
                    ElseIf sDataTypes = "integer" Then
                        cmd.Parameters.Add(sParamName, MySqlDbType.Int32, 3, sDataValue)
                        cmd.Parameters(sParamName).Direction = ParameterDirection.Input
                    ElseIf sDataTypes = "double" Then
                        cmd.Parameters.Add(sParamName, MySqlDbType.Double, 5, sDataValue)
                        cmd.Parameters(sParamName).Direction = ParameterDirection.Input
                    ElseIf sDataTypes = "varchar" Then
                        cmd.Parameters.Add(sParamName, MySqlDbType.VarChar, 200, sDataValue)
                        cmd.Parameters(sParamName).Direction = ParameterDirection.Input
                    Else
                        cmd.Parameters.Add(sParamName, MySqlDbType.DateTime, 200, sDataValue)
                        cmd.Parameters(sParamName).Direction = ParameterDirection.Input
                    End If
                Next lCtr
            End If
        End If
        MessageBox.Show(cmd.Parameters(sParamName).Value) 'The result is 0
        cmd.ExecuteNonQuery()
        conn.Close()
        InsertUpdateData = True
        Exit Function
    Catch ex As MySqlException
        MessageBox.Show(ex.Message)
    End Try
End Function

/表格

       sParameterList = "intPlayerAccountId$integer$" & Label_PlayerAccountID.Text &
            "|intStudentId$integer$" & defaultValue &
            "|intSemesterId$integer$" & defaultValue &
            "|intEducation$integer$" & defaultValue &
            "|intPayment$integer$" & defaultValue &
            "|dblAmount$integer$" & dblCreditedAmount &
            "|dblCreditedAmount$integer$" & dblCreditedAmount &
            "|dblAvailableBalance$integer$" & Label_CurrentBalance.Text &
            "|intStatus$integer$" & defaultValue &
            "|intRequestStatus$integer$" & defaultValue &
            "|intProcessedBy$integer$" & 163 &
            "|intParentId$integer$" & Label_Walletid.Text
        bool = objDataInquiry.InsertUpdateData("sp_Enrollment", sParameterList, 12)

更新

我收到同样的错误PROCEDURE 的参数数量不正确...预期为 12。但为 0

【问题讨论】:

我会做出一个疯狂的猜测,这意味着提供给 PROCEDURE 的参数数量是错误的,它应该是 12,但没有给出。请注意,您的代码正在解析某种字符串以获取参数,但我们看不到该字符串是如何提供给您的例程的。 好的,我会更新我的问题,请稍候 没有必要将Direction 设置为Input,因为这是默认设置。但是,如果您要设置它,则不会在每个 If 块中设置它,因为这样您就一遍又一遍地编写相同的代码。在End If 之后,您只需执行一次。 呃,这全是 25 年前的 VB6 时代的旧模式 不要使用字符串来尝试传递参数,而应该使用MySqlParameterCollection。 【参考方案1】:

下面的代码使用了更现代的编码风格,但我需要强调这不仅仅是关于美学。除了解决问题中的问题之外,这种方法还解决了您可能没有的几个问题了解:

    原始代码围绕共享连接创建争用,强制操作按顺序进行,否则可能是异步的,并通过干扰已经提供的现有连接池功能使单个查询的处理速度变慢盒子。 如果抛出异常,原始代码不会关闭连接。如果这种情况足够多,它可能会将您锁定在数据库之外。 “s”和“arr”等类型前缀是 Microsoft 发明的。根据当时的编码风格、语言特性和工具,它们对 VB6 时代的代码有意义。借助 .Net 中改进的工具和语言概念,Microsoft 自己的样式指南现在明确要求您不要使用类型前缀。 异常处理不应在此方法中完成,而应由调用此方法的代码进行更高级别的处理。
' Do NOT try to re-use the same connection object throughout your app!
Using conn As New MySqlConnection("connection string here"), _
      cmd  As New MySqlCommand(StoredProcName, conn)

    cmd.CommandType = CommandType.StoredProcedure

    If String.IsNullOrWhitespace(ParameterList) Then Return False       ​
    ​Dim QueryParams = ParameterList.Split("|"c)
    ​If QueryParams.Length = 0 Then Return False
​
    ​For Each param As String In QueryParams
        Dim ParamFields = param.Split("$"c)
        Dim ​ParamName As String = ParamFields(0)
        Dim DataType  As String = ParamFields(1)
        Dim DataValue As String = ParamFields(2)

        Select Case DataType
            Case "string", "varchar" 
                ​cmd.Parameters.Add(ParamName, MySqlDbType.VarChar, 200).Value = DataValue
            Case "integer"
                ​cmd.Parameters.Add(ParamName, MySqlDbType.Int32).Value = DataValue
        ​    Case "double" 
            ​    cmd.Parameters.Add(ParamName, MySqlDbType.Double, 5).Value = DataValue
        ​    Case Else
                cmd.Parameters.Add(ParamName, MySqlDbType.DateTime).Value = DataValue
        End Select
    ​Next param
    conn.Open()
   ​ cmd.ExecuteNonQuery()
    Return True
End Using

每个 VarChar 字段真的有 200 个字符吗?这似乎是一个非常糟糕的主意。您需要处理更长的字段只是时间问题。此外,当您的参数数据包含管道 (|) 或美元符号 ($) 作为文本的一部分时,您认为会发生什么?你真的应该将这些数据作为它自己的类类型发送,而不是需要解析出一个字符串。

【讨论】:

【参考方案2】:

问题是您仍在错误地创建参数。你以前错了,你把它改成了别的错。您正在使用的Add 的重载用于在数据适配器上调用Update 以保存来自DataTable 的更改。第四个参数是要从中获取数据的列的名称,而不是值。实际上,您没有为任何参数提供任何值,因此错误消息会告诉您。

正确创建参数。对需要大小的数据类型使用 Add 的重载:

cmd.Parameters.Add(sParamName, MySqlDbType.VarChar, 200).Value = sDataValue

对于那些不这样做的人来说,这个重载:

cmd.Parameters.Add(sParamName, MySqlDbType.Int32).Value = sDataValue

【讨论】:

请看图片

以上是关于无法将参数发送到 MySQL 存储过程窗口窗体的主要内容,如果未能解决你的问题,请参考以下文章

将字符串参数发送到存储过程

将参数发送到引导模式窗口?

SQL 存储过程和数据集

将回调作为参数发送到 QJSValue::callAsConstructor()

SQL Server 2005 使用 GETDATE() 作为参数通过 SSIS 运行存储过程

IBM worklight - 如何将请求参数发送到 PHP 文件?