无法将参数发送到 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
下面的代码使用了更现代的编码风格,但我需要强调这不仅仅是美学问题。除了解决问题中的问题外,这种方法还解决了几个问题您可能不知道的问题:
- 原始代码围绕共享连接创建争用,强制按顺序执行原本可能异步的操作,并通过干扰现有连接池使单个查询的速度变慢开箱即用的能力。
- 如果抛出异常,原始代码不会关闭连接。如果这种情况发生的次数足够多,它可能会将您锁定在数据库之外。
- 像“s”和“arr”这样的类型前缀是微软发明的。基于当时的编码风格、语言特性和工具,它们对 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 个字符长吗?这似乎是一个 非常糟糕的主意 。您需要处理更长的字段只是时间问题。此外,当您的参数数据包含竖线 (|
) 或美元符号 ($
) 作为文本的一部分时,您认为会发生什么情况?您真的应该按照自己的 class 类型发送此数据,而不是需要解析字符串。
我正在尝试使用 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
下面的代码使用了更现代的编码风格,但我需要强调这不仅仅是美学问题。除了解决问题中的问题外,这种方法还解决了几个问题您可能不知道的问题:
- 原始代码围绕共享连接创建争用,强制按顺序执行原本可能异步的操作,并通过干扰现有连接池使单个查询的速度变慢开箱即用的能力。
- 如果抛出异常,原始代码不会关闭连接。如果这种情况发生的次数足够多,它可能会将您锁定在数据库之外。
- 像“s”和“arr”这样的类型前缀是微软发明的。基于当时的编码风格、语言特性和工具,它们对 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 个字符长吗?这似乎是一个 非常糟糕的主意 。您需要处理更长的字段只是时间问题。此外,当您的参数数据包含竖线 (|
) 或美元符号 ($
) 作为文本的一部分时,您认为会发生什么情况?您真的应该按照自己的 class 类型发送此数据,而不是需要解析字符串。