了解ExecuteNonQuery的返回值

时间:2016-08-17 04:23:55

标签: c# mysql stored-procedures

首先,为了清楚起见,我认识到ExecuteNonQuery只应用于UPDATE, INSERT, or DELETE语句,而对于所有其他类型的语句,例如SELECT,返回值为-1。

我的问题是,为什么以下存储过程:

CREATE PROCEDURE `ExampleProc`(IN Name varchar(60), OUT ID bigint(20), OUT SP varchar(255))
BEGIN
    SELECT id, sp INTO ID, SP FROM users WHERE username = Name;
END

使用ExecuteNonQuery执行时:

using (var conn = new MySqlConnection("Secret"))
{
    conn.Open();
    using (var cmd = new MySqlCommand("ExampleProc", conn) { CommandType = CommandType.StoredProcedure })
    {
        cmd.Parameters.AddWithValue("Name", request.Name).MySqlDbType = MySqlDbType.VarChar;
        cmd.Parameters.Add("ID", MySqlDbType.Int64).Direction = ParameterDirection.Output;
        cmd.Parameters.Add("SP", MySqlDbType.VarChar).Direction = ParameterDirection.Output;
        var returnVal = cmd.ExecuteNonQuery();
    }
}

如果找不到名称的行,则会产生0 in returnVal,如果找到,则会产生1?根据我读过的所有文档,由于存储过程包含single SELECT statement,我应该看到-1无论如何返回。相反,它会返回受影响/找到的行数,这根据文档没有意义。

最后,我还尝试使用"SELECT *" instead of "SELECT id, sp INTO ID, SP"。这似乎总是返回0。仍然不是我期待的-1

1 个答案:

答案 0 :(得分:1)

让我们了解ADO.Net中ExecuteNonQuery API的工作原理,正如您从文档中了解的那样,它应提供受DML查询影响的行数和Select查询的-1。

但是内部工作是这样的,如果是Sql Server,默认设置为Set NoCount Off有助于写入TDS protocol,修改的行数和Ado读取的数量相同.Net API,因此是正确的结果,这是ado.netSql Server的原生二进制整合的结果。更多详情请访问以下链接:

Ado.Net TDS Protocol

SET NOCOUNT ON usage

对于其他数据库,例如MySqlOracle,不能保证相同的行为,因为它们的集成与Sql Server不在同一级别。这是问题中发布的差异的主要原因,使其在整个数据库中保持一致,您可能希望依靠Output Parameter在过程内部自动填充值,因为每个数据库都有机制来计算超出更新的行数

相关问题