-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);