VB.NET MySqlCommand存储过程参数顺序?

时间:2012-05-12 16:59:11

标签: mysql vb.net mysql-connector

我在函数中创建一个字典,然后传递给执行sproc的函数。

    Dim PParamDict As New Dictionary(Of String, String)
    PParamDict.Add("sname", name)
    PParamDict.Add("sdescription", description)
    PParamDict.Add("sLoggedInID", LoggedInID)
    PParamDict.Add("sCompanyID", CompanyID)

字典被传递给函数PParamDict - > ParameterDict

    Dim dbComm As New MySqlCommand(ProcedureName, PConnection)

    Dim pair As KeyValuePair(Of String, String)
    For Each pair In ParameterDict
        dbComm.Parameters.AddWithValue(pair.Key, pair.Value)
    Next

从字典中添加参数。

这是一个简单的特色,没什么特别的,简单的插入。

CREATE PROCEDURE `NewCollection`(
IN `sLoggedInID` INT(5), 
IN `sCompanyID` INT(5), 
IN `sname` VARCHAR(20),  
IN `sdescription` VARCHAR(500))

BEGIN
INSERT INTO `collection`
(`userid`, `companyid`, `name`, `description`, `generated`) 
VALUES 
(sLoggedInID, sCompanyID, sname, sdescription, CURRENT_TIMESTAMP);
END

只要PParamDict.Add语句按此顺序排列,就可以正常工作。如果它们处于不同的顺序,它们会在它们进入时通过。这是我见过的最荒谬的事情,我将该死的密钥传递给MySqlCommand,它是在sproc中定义的字母。我一定错过了什么,请帮忙!

2 个答案:

答案 0 :(得分:1)

我有类似的问题,但是我的参数值列表是通过反射来实现的,因此我不会手动构建列表并且无法控制订单。

在Pete的回答中,参数的绑定将始终按正确的顺序排列,因为它不是存储过程,而是一个文本命令,其中参数名称用作占位符,因此它们的顺序无关紧要加入。

为了解决排序问题,我只是简单地将过程称为文本(如Pete的INSERT)而不是像这样使用command.CommandType = System.Data.CommandType.StoredProcedure:

command.CommandText = "call procname (@param1, @param2, @param3 ... );"

然后我可以按我想要的任何顺序添加参数

command.Parameters.AddWithValue("@param3", 123)
command.Parameters.AddWithValue("@param2", 456)
command.Parameters.AddWithValue("@param1", 789)

希望这有帮助。

编辑:如果您有输出参数

,此方法将无效

答案 1 :(得分:0)

也许这会有所帮助。 StringDictionaryimplements a hash table with the key and the value strongly typed to be strings rather than objects”。

HashTablerepresents a collection of key/value pairs that are organized based on the hash code of the key”。

当您向StringDictionary添加对时,它会被密钥字符串的哈希码重新组织。

如果您构建SqlParameterCollection而不是StringDictionary,那么您的参数将被命名,并且for each迭代器应该很好地匹配您的sproc中的参数。

<强>更新

添加代码示例。

Private Function GetParameters(ByVal name As String, ByVal description As String, ByVal LoggedInID As Integer, ByVal CompanyID As Integer) As SqlParameterCollection
    Dim cmd As SqlCommand = New SqlCommand()
    Dim pc As SqlParameterCollection = cmd.Parameters 'SqlParameterCollection constructor is marked as "Friend" so it has to be instantiated this way.'

    pc.AddWithValue("sname", name)
    pc.AddWithValue("sdescription", description)
    pc.AddWithValue("sLoggedInID", LoggedInID)
    pc.AddWithValue("sCompanyID", CompanyID)

    Return pc
End Function

Private Sub ExecuteStoredProcedure(ByVal pc As SqlParameterCollection)
    Dim sp As String = String.Empty
    Dim conn As SqlConnection = Nothing
    Dim cmd As SqlCommand = Nothing
    Dim da As SqlDataAdapter = Nothing
    Dim ds As DataSet = Nothing
    Dim p As SqlParameter = Nothing

    Try
        sp = "INSERT INTO `collection` (`user_id`, `company_id`, `name`, `description`, `generated`) VALUES (`sLoggedInID`, `sCompanyID`, `sname`, `sdescription`, CURRENT_TIMESTAMP)"
        conn = New SqlConnection("your connection string here")
        cmd = New SqlCommand(sp, conn)
        For Each p In pc
            cmd.Parameters.Add(p)
        Next

        da = New SqlDataAdapter(cmd)
        ds = New DataSet
        da.Fill(ds)

    Catch ex As SqlException
        'handle exception'
    Catch ex As Exception
        'handle exception'
    Finally
        If conn IsNot Nothing Then
            conn.Dispose()
        End If
        If cmd IsNot Nothing Then
            cmd.Dispose()
        End If
        If da IsNot Nothing Then
            da.Dispose()
        End If
    End Try
End Sub