【问题标题】:SqlParameter not supplied when using Parameters.AddWithValue使用 Parameters.AddWithValue 时未提供 SqlParameter
【发布时间】:2019-12-13 17:07:18
【问题描述】:

这就是我设置命令的方式。它在第一个参数 UpdateType 处停止。此代码正在从 VB.NET 2008 版本更新。

Dim db As New DB()
Dim cmd As SqlCommand = New SqlCommand()

'Put into an object, and use AddWithValue due to Parameters.Add being deprecated.
Dim UpdateType As String = "PARAMETERS"

If IsNewJob Then
  cmd.CommandText = "sp_MB_AddJob"
Else
  cmd.CommandText = "sp_MB_UpdateJob"
  cmd.Parameters.AddWithValue("@UpdateType", SqlDbType.NVarChar).Value = UpdateType
  cmd.Parameters.AddWithValue("@OrigJobName", OrigJobName.ToString)
End If

cmd.Parameters.AddWithValue("@UserID", CInt(Utils.GetLoggedInUserID))
cmd.Parameters.AddWithValue("@ProjectName", ProjectName.ToString)

【问题讨论】:

  • Add(String, Object) 已弃用,而不是 Add(String, SqlDbType)。将Parameters.Add 用于您的@UpdateType 参数(如果它们不被视为对象,则使用其他参数)。 SqlParameterCollection.Add MethodAddWithValue 不支持提供数据类型。
  • 您也没有将 CommandType 设置为 StoredProcedure。而且您确实应该使用与 sp_ 不同的前缀,或者甚至完全不使用前缀。 sqlperformance.com/2012/10/t-sql-queries/sp_prefix
  • 让我们更清楚一点 - 不要使用addwithvalue
  • 你的一个字符串可能什么都不是。如果 db 字段允许 null,则在您的字符串为空时使用 SqlString.Null。
  • 这里的IsNewJob 是什么,没有定义。

标签: sql-server vb.net sqlcommand


【解决方案1】:

您应该使用.Add 来代替NVARCHARVARCHARVARBINARY 的类型和 与长度。在这里,我将展示如何处理您在问题中遇到的问题,我只是为了示例而编造了长度。使用 AddWithValue 会对 SQL 性能和其他方面产生负面影响。

可以在许多地方找到一些对您有帮助的信息,包括这里https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/configuring-parameters-and-parameter-data-types

Dim db As New DB()
Dim cmd As SqlCommand = New SqlCommand()
Dim UpdateType As String = "PARAMETERS"
cmd.CommandType = CommandType.StoredProcedure

If IsNewJob Then
  cmd.CommandText = "sp_MB_AddJob"
Else
  cmd.CommandText = "sp_MB_UpdateJob"
  cmd.Parameters.Add("@UpdateType", SqlDbType.NVarChar, 10).Value = UpdateType
  cmd.Parameters.Add("@OrigJobName", SqlDbType.NVarChar, 50).Value = OrigJobName.ToString
End If
cmd.Parameters.Add("@UserID", SqlDbType.Int).Value = CInt(Utils.GetLoggedInUserID)
cmd.Parameters.Add("@ProjectName", SqlDbType.NVarChar, 30).Value = ProjectName.ToString

【讨论】:

  • 注意,我没有处理丢失的IsNewJob,假设它存在
  • SQLParameter.Size 的默认值被推断为值大小,因此如果您有一个长长度值,则缓冲区将会更多。所以如果你有一个定义的大小,如果值大于大小,它也可以被截断。
  • 在 .Add(String, SqlDbType, Int, String) 方法中,最终的字符串是源列名。您的代码根本不传递任何值。
  • @Mary 你说得对,我解决了这个问题,我几乎从不使用这种形式,主要是单独设置参数属性,而不是 VB。
  • 这真的应该分成sp_MB_AddJob的一种方法和sp_MB_UpdateJob的一种方法
【解决方案2】:

将您的数据库对象保留在使用它们的方法的本地,以便您可以控制它们是否被关闭和处置。 `Using...End Using 块会为你解决这个问题。请注意,单个 Using 块同时处理连接和命令。

.Add 方法并未被弃用。过时的是.Add(String, Object) 过载。 `.AddWithValue 肯定不受欢迎。见http://www.dbdelta.com/addwithvalue-is-evil/https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/ 还有一个: https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications 这是另一个 https://andrevdm.blogspot.com/2010/12/parameterised-queriesdont-use.html

我不得不猜测参数的数据类型和列大小。检查您的数据库中的实际值并相应地更正代码。

Private Sub OpCode()
    Dim UpdateType As String = "PARAMETERS"
    Using cn As New SqlConnection("Your connection string"),
            cmd As New SqlCommand()
        cmd.Connection = cn
        If IsNewJob Then
            cmd.CommandText = "sp_MB_AddJob"
        Else
            cmd.CommandText = "sp_MB_UpdateJob"
            cmd.Parameters.Add("@UpdateType", SqlDbType.NVarChar, 50).Value = UpdateType
            cmd.Parameters.Add("@OrigJobName", SqlDbType.NVarChar, 200).Value = OrigJobName.ToString
        End If

        cmd.Parameters.Add("@UserID", SqlDbType.Int).Value = CInt(Utils.GetLoggedInUserID)
        cmd.Parameters.Add("@ProjectName", SqlDbType.NVarChar, 200).Value = ProjectName.ToString
        cn.Open()
        cmd.ExecuteNonQuery()
    End Using
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 2016-07-05
    • 2018-08-15
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    相关资源
    最近更新 更多