2015-11-24 37 views
2

-edit-写了一个更清楚的解释什么是不工作的底部。也许只是跳到那个。存储过程产生不同的结果从c#调用.net

我有一个存储过程,我写了一个问题,得到的结果在我的C#应用​​程序,但是当我MySQL基准内执行它的结果返回的罚款。

首先的步骤是:

CREATE DEFINER=`root`@`localhost` PROCEDURE `GetNextOpponent`(IN p_user_id INT, OUT p_target_id INT, OUT p_target_data MEDIUMBLOB, OUT p_target_rank INT) 
BEGIN 
    DECLARE UserRank INT; 

    CALL DeleteOldSearches(); /* TODO remove and call on interval instead of every time*/ 

    SET UserRank = (SELECT rank FROM world WHERE user_id = p_user_id); 

    IF UserRank IS NOT NULL 
    THEN 
     SELECT user_id, world_data, rank 
     INTO p_target_id, p_target_data, p_target_rank 
     FROM world 
     WHERE 
      user_id != p_user_id AND 
      user_id NOT IN (SELECT target_id FROM searches WHERE user_id = p_user_id) AND 
      shield < CURRENT_TIMESTAMP 
     ORDER BY ABS(UserRank - 3) 
     LIMIT 1; 
    END IF; 

    IF p_target_id IS NOT NULL 
    THEN 
     INSERT INTO searches (user_id, target_id) 
     VALUES (p_user_id, p_target_id); 
    END IF; 

    /*SELECT TargetID, TargetData, TargetRank;*/ 
END 

现在,如果我

call battlecraft_test.GetNextOpponent(1, @p_target_id, @p_target_data, @p_target_rank); 
select @p_target_id, @p_target_data, @p_target_rank; 

我没有问题,把它在工作台,得到一个不错的结果

'3', BLOB, '2' 

但是如果我在我的应用程序中执行它,

 public static bool GetNextOpponent(int userID) 
     { 
      MySqlConnection conn = null; 

      try 
      { 
       conn = new MySqlConnection(ConnectionString); 
       conn.Open(); 

       using (var cmd = new MySqlCommand("GetNextOpponent", conn) {CommandType = CommandType.StoredProcedure}) 
       { 
        cmd.Parameters.Add("@p_user_id", MySqlDbType.Int32).Value = userID; 
        cmd.Parameters.Add("@p_target_id", MySqlDbType.Int32).Direction = ParameterDirection.Output; 
        cmd.Parameters.Add("@p_target_data", MySqlDbType.MediumBlob).Direction = ParameterDirection.Output; 
        cmd.Parameters.Add("@p_target_rank", MySqlDbType.Int32).Direction = ParameterDirection.Output; 

        cmd.ExecuteNonQuery(); 

        object a = cmd.Parameters["@p_target_id"].Value; // null 
        object b = cmd.Parameters["@p_target_data"].Value; // null 
        object c = cmd.Parameters["@p_target_rank"].Value; // null =(

        return true; 
       } 
      } 
      catch (Exception ex) 
      { 
       Logger.LogError($"Unexpected exception of type {ex.GetType()}: {ex.Message}"); 
       return false; 
      } 
      finally 
      { 
       conn?.Close(); 
      } 
     } 

out参数都是null。

有,我已经有了结果了,从我的应用程序,例如大多数时候,如果我步的每行代码,同时调试它工作正常,但大多数的什么也没有发生时的一些有趣的案例。

我真的为此而努力,现在花了几个小时就可以了 - 我的数据库知识不如我想它是在那一刻,我的想法,所以我希望有人有一个想法是什么。

我的一个尝试我试着不使用OUT关键字,而不是仅仅返回现场,用的ExecuteReader反而但它仍然只是有时工作来解决这个的。

如果我写了另一个程序,一种包装这个过程就像这样:

CREATE DEFINER=`root`@`localhost` PROCEDURE `test`(IN p_user_id INT) 
BEGIN 
    call battlecraft_test.GetNextOpponent(p_user_id, @p_target_id, @p_target_data, @p_target_rank); 
    select @p_target_id, @p_target_data, @p_target_rank; 
END 

它的工作原理,当我使用阅读器执行它,但是第一行总是空,第二行有结果。这是一种可用的解决方法,但我宁愿去解决它的原因。

感谢提前任何回应。

-edit-

即使剥离它我也有问题。如果我减少存储过程只是

CREATE DEFINER=`root`@`localhost` PROCEDURE `GetNextOpponent`(IN p_user_id INT) 
BEGIN 
    SELECT user_id, world_data, rank 
    FROM world 
    WHERE 
     user_id != p_user_id AND 
     user_id NOT IN (SELECT target_id FROM searches WHERE user_id = p_user_id) AND 
     shield < CURRENT_TIMESTAMP 
    ORDER BY ABS((SELECT rank FROM world WHERE user_id = p_user_id) - rank) 
    LIMIT 1; 
END 

,然后实现它作为一个读者

public static bool GetNextOpponent(int userID) 
    { 
     MySqlConnection conn = null; 

     try 
     { 
      conn = new MySqlConnection(ConnectionString); 
      conn.Open(); 

      using (var cmd = new MySqlCommand("GetNextOpponent", conn)) 
      { 
       cmd.CommandType = CommandType.StoredProcedure; 

       cmd.Parameters.Add("@p_user_id", MySqlDbType.Int32).Value = userID; 

       //System.Threading.Thread.Sleep(1000); // Un-commenting this makes it work... 

       using (var rdr = cmd.ExecuteReader()) 
       { 
        if (!rdr.Read()) 
         return false; // returns here 

        var r1 = rdr.GetValue(0); // null 
        var r2 = rdr.GetValue(1); // null 
        var r3 = rdr.GetValue(2); // null 

        return true; 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      Logger.LogError($"Unexpected exception of type {ex.GetType()}: {ex.Message}"); 
      return false; 
     } 
     finally 
     { 
      conn?.Close(); 
     } 
    } 

而在工作台执行仍然会返回一个不错的结果

call battlecraft_test.GetNextOpponent(1); 

回答

0

有很多事情要在你的代码中得到改进

在try/catch验证和关闭的finally块中E中的连接

不要使用通用捕捉尽可能捕捉使用(“DatabaseSpecificExceptions”或“RunTimeExceptions”或任何其他预期厚望”的第一级和日志文件或通过电子邮件进行调试进一步加强

public static bool GetNextOpponent(int userID) 
    { 
     MySqlConnection conn = null; 
     boolean resp ; 

     //we assume that if fails 
     resp = false ; 

     try 
     { 
      conn = new MySqlConnection(ConnectionString); 

    if(conn != null) 
    { 
      conn.Open(); 

      using (var cmd = new MySqlCommand("GetNextOpponent", conn) {CommandType = CommandType.StoredProcedure}) 
      { 
      //Addding parameters to the SQL commands - good comments never hurt 

       cmd.Parameters.Add("@p_user_id", MySqlDbType.Int32).Value = userID; 
       cmd.Parameters.Add("@p_target_id", MySqlDbType.Int32).Direction = ParameterDirection.Output; 
       cmd.Parameters.Add("@p_target_data", MySqlDbType.MediumBlob).Direction = ParameterDirection.Output; 
       cmd.Parameters.Add("@p_target_rank", MySqlDbType.Int32).Direction = ParameterDirection.Output; 

         //you are executing a NonQuery but expectin results ?? 
       cmd.ExecuteNonQuery(); 

      //see comments above 
       object a = cmd.Parameters["@p_target_id"].Value; // null 
       object b = cmd.Parameters["@p_target_data"].Value; // null 
       object c = cmd.Parameters["@p_target_rank"].Value; // null =(

         //avoid returns in the middle of the flow until debug works 
       //return true; 
         resp = true ; 
      } 
    } 
     } 
     catch (Exception ex) 
     { 
      Logger.LogError($"Unexpected exception of type {ex.GetType()}: {ex.Message}"); 
     } 
     finally 
     { 
    if(conn != null) 
      { 
       conn?.Close(); 
      } 
     } 
    } 
相关问题