2016-08-17 64 views
2

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

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

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

+0

检查链接 https://msdn.microsoft.com/en-in/library/ms188774.aspx 对于Select语句尝试设置'Set RowCount '并测试。另外请注意你提到的行为是针对Sql Server的,对于不同的数据库可能表现不同 –

回答

1

让我们了解了ADO.Net的ExecuteNonQuery API的工作,因为你已经远离了它应提供影响为DML查询和-1为Select查询的一部分行数的文件的理解。

但是内部工作是这样的,在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自动填充过程中的值,因为每个数据库都有机制来计算出数量行更新

+0

谢谢你的回答。看起来奇怪的是会有差异,尤其是因为在MySQL文档中正确描述了相同的行为:https://dev.mysql.com/doc/dev/connector-net/html/M_MySql_Data_MySqlClient_MySqlCommand_ExecuteNonQuery.htm。此外,作为一个测试,而不是存储过程,我使用“SELECT * FROM users”设置了MySqlCommand并返回-1,因此看起来存储过程的工作方式有问题。有小费吗? – Eaton

+0

@Eaton需要更深入细节,尽管您发布的链接提供了相同的细节,但我确定有一些方面或像'My Sql'这样的'Sql Server'的'NoCountON'设置,需要探索,以了解行为的偏差 –

+0

我做了一些研究,找不到任何东西。NOCOUNT似乎没有在MySQL中以任何形式使用。 – Eaton