【问题标题】:SQL Server doesn't recognize my parameterSQL Server 无法识别我的参数
【发布时间】:2015-02-21 16:42:45
【问题描述】:

我有一个带有管理页面的 ASP.NET MVC 站点,我需要在其中合并两条记录。我传入了两个值,@old@new。将这些添加到我的SqlCommand 对象后,我调用ExecuteNonQuery()。这会产生一个异常,消息说

存储过程“FixDuplicate”需要参数“@old”,它是 未提供

正如您在下面看到的,我肯定会添加参数。我试过的所有 3 个版本都在那里。

这段代码有什么问题?

版本一:(请忽略这个的语法,我已经把这段代码去掉了,但我确实试过了,在到达ExecuteNonQuery()调用时确认参数存在)

var sql = "FixDuplicate";

comm.Parameters.Add(new System.Data.SqlClient.SqlParameter("@old", model.Duplicate));
comm.Parameters.Add(new System.Data.SqlClient.SqlParameter("@new", model.Primary));

_dataAccessService.ExecuteSql(conn, comm);

版本 2:

comm.Parameters.AddWithValue("@old", model.Duplicate);
comm.Parameters.AddWithValue("@new", model.Primary);

版本 3:

comm.Parameters.Add("@old", System.Data.SqlDbType.Int);
comm.Parameters[0].Value = model.Duplicate;
comm.Parameters.Add("@new", System.Data.SqlDbType.Int);
comm.Parameters[1].Value = model.Primary;

最后,这是_dataAccessService.ExecuteSql(conn, comm) 调用中的代码:

public void ExecuteSql(SqlConnection connection, SqlCommand command, bool closeConnection = true)
{
    if (connection == null)
        throw new ArgumentNullException("connection");

    if (command == null)
        throw new ArgumentNullException("command");

    try
    {
        if (connection.State != ConnectionState.Open)
            connection.Open();

        try
        {
            command.ExecuteNonQuery();
        }
        catch
        {
            throw;
        }
        finally
        {
            if (closeConnection)
                command.Dispose();
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Sorry, an error occurred ExecuteSql: " + ex.Message, ex);
    }
    finally
    {
        if (closeConnection)
            connection.Dispose();
    }
}

注意:我已确认“@old”和“@new”的值在到达ExecuteNonQuery() 行时已设置。

编辑:这是完整的代码,因为它存在:

// Here we need to execute the "FixDuplicate" stored procedure
var sql = "FixDuplicate";
var conn = _dataAccessService.GetConnection("");
var comm = _dataAccessService.GetCommand(conn, sql, System.Data.CommandType.StoredProcedure);

//comm.Parameters.AddWithValue("@old", model.DuplicateWrestler);
//comm.Parameters.AddWithValue("@new", model.PrimaryWrestler);
comm.Parameters.Add("@old", System.Data.SqlDbType.Int);
comm.Parameters[0].Value = model.DuplicateWrestler;
comm.Parameters.Add("@new", System.Data.SqlDbType.Int);
comm.Parameters[1].Value = model.PrimaryWrestler;

_dataAccessService.ExecuteSql(conn, comm);

【问题讨论】:

  • 您是否考虑过创建一个辅助类或您自己的自定义类来传递参数并将它们添加到 foreach 循环中我将发布一个您可以做什么的示例
  • 您确定 model.Duplicate 不为空吗?
  • @Salim 是的,我在问题中添加了“注释”...
  • 添加参数后,为什么不通过实际名称而不是索引来分配其@param 名称的值,例如comm.Parameters["@old"].Value = model.DuplicateWrestler; 我认为您可能还想参考@987654336 @方法在这里SqlCommand.Parameters.Add Method
  • @DJKRAZE 我不是已经在调用 SqlCommand.Parameters.Add 方法了吗?

标签: c# sql-server asp.net-mvc sql-server-2008 sql-server-2008-r2


【解决方案1】:

您的model.Duplicate 可能是null。在这种情况下,参数的值不会被设置

如果您需要将null 传递给SqlParameter.Value,请使用DBNull.Value

参考SqlParameter.Value

【讨论】:

  • 不,每次设置断点时,我都会确认已填充“@old”和“@new”,并设置为正确的值。
  • 只是为了确认这一点(现在我在工作而不是坐在我的代码前面)。我刚刚进行了检查以确保两个值都大于 0。一旦我的云提供商构建和部署,我将再次运行并确保...
  • 我添加了一个检查来查看 model.Primary > 0 和 model.Duplicate > 0 并且它没有返回验证错误。
  • 这就是为什么我建议 NullCoalesce 的原因首先是价值观
  • 所以如果值为 null 那么你可以做这样的事情comm.Parameters[0].Value = model.DuplicateWrestler ?? DBNULL.Value;
【解决方案2】:

我相信你需要指定一个命令类型:

command.CommandType = CommandType.StoredProcedure;

【讨论】:

  • 对不起,这已经存在,我删除了,我认为是不必要的代码行。我将使用正在生产中的完整版本进行更新...
【解决方案3】:

我建议你检查一下 Profiler 是否设置了旧参数。 并尝试从 SQL Server Management Studio 运行此过程,以确保它工作正常。

【讨论】:

  • 几个月来我一直在直接从 SSMS 运行存储过程,我现在正试图将它添加到应用程序中,因为我无法在工作中使用 SSMS(它们阻止访问 Sql云提供商)。 Profiler 的好主意,这将确认它可能 [不] 存在。我回家后一定要试试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多