0

我在传递给执行存储过程的函数的函数中创建了一个字典。

    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,它们是在存储过程中逐个字母定义的。我一定错过了什么,请帮忙!

4

2 回答 2

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)

希望这可以帮助。

编辑:如果您有输出参数,此方法将不起作用

于 2013-10-18T11:23:42.340 回答
0

也许这会有所帮助。A StringDictionary实现了一个哈希表,其中键和值被强类型化为字符串而不是对象”。

一个HashTable表示基于键的哈希码组织的键/值对的集合”。

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

如果您构建 aSqlParameterCollection而不是 a StringDictionary,则您的参数被命名并且for each迭代器应该很好地匹配您的存储过程中的参数。

更新

添加代码示例。

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
于 2012-05-12T17:49:34.377 回答