ASP.NET调用SQL Server分页存储过程返回-1问题求助
解决ASP.NET调用SQL Server存储过程返回-1而非预期页数的问题
问题原因
你拿到的-1是ExecuteNonQuery()的返回值,这个方法专门用于执行不返回结果集的SQL语句(如INSERT/UPDATE/DELETE),它的返回值是受这些语句影响的行数。你的存储过程仅做了查询和PRINT操作,没有修改任何数据,所以返回-1是正常行为,这个值和你需要的总页数完全无关。
你期望的3是存储过程中PRINT输出的内容,虽然InfoMessage事件捕获到了该消息,但你的代码并没有将这个消息作为方法返回值,反而错误地返回了ExecuteNonQuery()的结果。
解决方案
推荐使用输出参数的方式从存储过程返回总页数,这是SQL Server存储过程返回业务数据的标准做法,比依赖PRINT消息更可靠。
步骤1:修改存储过程,添加输出参数
ALTER PROCEDURE [dbo].[NUMPAG] (@pagenumber AS int = 1, @itensQTD AS int = 5, @pagtotal AS int OUTPUT) -- 新增输出参数,用于返回总页数 AS BEGIN SELECT @pagtotal = CEILING(CAST(COUNT(*) AS numeric(18, 2)) / CAST(@itensQTD AS numeric(18, 2))) FROM ProdutoVenda; IF @pagenumber < 1 BEGIN SET @pagenumber = 1 END IF @pagenumber > @pagtotal BEGIN SET @pagenumber = @pagtotal END -- 可选保留PRINT,用于调试 PRINT @pagtotal END
步骤2:修改ASP.NET代码,获取输出参数的值
public int UltimaPAG() { var connectionString = "Data Source=" + Environment.MachineName + ";Initial Catalog=Projeto1;Integrated Security=True"; using (var connection = new SqlConnection(connectionString)) using (var command = new SqlCommand("dbo.NUMPAG", connection)) { command.CommandType = CommandType.StoredProcedure; // 添加输入参数 command.Parameters.AddWithValue("@pagenumber", 1); command.Parameters.AddWithValue("@itensQTD", 5); // 定义输出参数 var outputParam = new SqlParameter("@pagtotal", SqlDbType.Int) { Direction = ParameterDirection.Output }; command.Parameters.Add(outputParam); connection.Open(); // 执行存储过程,无需关心ExecuteNonQuery的返回值 command.ExecuteNonQuery(); connection.Close(); // 从输出参数中提取总页数并返回 return (int)outputParam.Value; } }
备选方案:捕获PRINT消息(不推荐)
如果不想修改存储过程,可以修改代码捕获InfoMessage中的PRINT内容并返回,但这种方式仅适合调试,不适合正式业务场景(若存储过程输出多条PRINT消息,会导致解析错误):
public int UltimaPAG() { var connectionString = "Data Source=" + Environment.MachineName + ";Initial Catalog=Projeto1;Integrated Security=True"; string totalPageMessage = string.Empty; using (var connection = new SqlConnection(connectionString)) using (var command = new SqlCommand("dbo.NUMPAG", connection)) { command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue("@pagenumber", 1); command.Parameters.AddWithValue("@itensQTD", 5); // 定义局部事件处理方法捕获PRINT消息 void OnInfoMessage(object sender, SqlInfoMessageEventArgs e) { totalPageMessage = e.Message; } connection.InfoMessage += OnInfoMessage; connection.Open(); command.ExecuteNonQuery(); connection.Close(); // 转换消息为整数返回 if (int.TryParse(totalPageMessage, out int totalPages)) { return totalPages; } else { // 处理转换失败的情况,比如抛出异常或返回默认值 throw new InvalidOperationException("无法解析存储过程返回的总页数"); } } }
总结
优先选择输出参数的方案,这是更规范、更可靠的业务数据传递方式。PRINT语句仅用于调试,不应该作为正式返回业务数据的手段。
内容的提问来源于stack exchange,提问作者Joao Lucas Costa
相关产品推荐
相关产品推荐

