无法将参数发送到 MySQL 存储过程 windows 表单

Can't send parameters to a MySQL Stored Procedure windows form

我正在尝试使用 vb.net 中的 class 在 mariadb 存储过程中插入数据,但我不断收到错误提示 程序的参数数量不正确 ...预计 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

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

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

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

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

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

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

  1. 原始代码围绕共享连接创建争用,强制按顺序执行原本可能异步的操作,并通过干扰现有连接池使单个查询的速度变慢开箱即用的能力。
  2. 如果抛出异常,原始代码不会关闭连接。如果这种情况发生的次数足够多,它可能会将您锁定在数据库之外。
  3. 像“s”和“arr”这样的类型前缀是微软发明的。基于当时的编码风格、语言特性和工具,它们对 VB6 时代的代码有意义。随着 .Net 中可用的改进工具和语言概念,Microsoft 自己的样式指南现在明确要求您不要使用类型前缀。
  4. 异常处理不应在此方法中完成,而应由调用此方法的代码在更高级别完成。
' 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 个字符长吗?这似乎是一个 非常糟糕的主意 。您需要处理更长的字段只是时间问题。此外,当您的参数数据包含竖线 (|) 或美元符号 ($) 作为文本的一部分时,您认为会发生什么情况?您真的应该按照自己的 class 类型发送此数据,而不是需要解析字符串。