存储过程返回正常但Controller中DataSet无数据问题排查求助
问题排查:存储过程返回数据但ASP.NET Controller中DataSet无数据
问题背景
你编写了一个用OPENJSON将JSON字符串转为键值对的存储过程PROC_NH_Journal_Tab1Data,直接执行能拿到包含key、value、type的预期结果,但在ASP.NET的GetAnswersFortab1方法中,通过SqlDataAdapter填充的DataSet只有表头,没有实际数据;而结构类似的其他存储过程却能正常返回数据。
相关代码
存储过程代码
CREATE PROCEDURE [dbo].[PROC_NH_Journal_Tab1Data] @EnterpriseId nvarchar, @exactgroup nvarchar AS declare @json nvarchar(max) set @json=(select Tab2Json from tbl_NH_T_JournalDataPost where EnterpriseId=@EnterpriseId and GroupName = @exactgroup) SELECT * FROM OPENJSON ( @json ) Return 0
Controller代码片段
public JsonResult GetAnswersFortab1(string exact) { string JSONresult = string.Empty; string EnterpriseId = "User"; try { SqlConnection sqlcon = new SqlConnection(con); SqlCommand cmd = new SqlCommand("[PROC_NH_Journal_Tab1Data]", sqlcon); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@EnterpriseId", EnterpriseId); cmd.Parameters.AddWithValue("@exactgroup", exact); sqlcon.Open(); SqlDataAdapter adapter = new SqlDataAdapter(); adapter.SelectCommand = cmd; DataSet data; data = new DataSet(); adapter.Fill(data, "Table2"); DataTable dt1 = data.Tables[0]; ViewBag.getJson = dt1; } // 原代码省略了catch和返回逻辑
存储过程中PRINT @json的结果
key value type emoji2 2 1 check2 on 1 check5 on 1 check7 on 1 hiddentext weds 1
问题根源
最可能的原因是存储过程的参数未指定长度!在SQL Server中,nvarchar如果不指定长度,默认长度是1。这意味着你在Controller中传入的EnterpriseId = "User"会被截断成"U",exact参数也会被截断为第一个字符,导致查询tbl_NH_T_JournalDataPost时找不到匹配的记录,@json变量为空,最终OPENJSON没有数据输出。
而你直接执行存储过程时,应该是手动传入了完整长度的参数,所以能正常查到数据。
解决方案
1. 修改存储过程,指定参数长度
根据你的业务需求给参数设置合适的长度,比如:
CREATE PROCEDURE [dbo].[PROC_NH_Journal_Tab1Data] @EnterpriseId nvarchar(50), -- 根据实际业务调整长度 @exactgroup nvarchar(100) -- 根据实际业务调整长度 AS declare @json nvarchar(max) set @json=(select Tab2Json from tbl_NH_T_JournalDataPost where EnterpriseId=@EnterpriseId and GroupName = @exactgroup) -- 增加ISNULL处理,避免@json为NULL时无输出 SELECT * FROM OPENJSON (ISNULL(@json, '{}')) Return 0
2. 优化Controller代码(可选但推荐)
- 使用
using语句自动释放数据库连接,避免资源泄漏 - 直接用表名获取DataTable,比索引更可靠
- 增加异常捕获和空数据日志,方便排查
- 补充返回逻辑(原代码似乎缺少
return语句)
优化后的代码示例:
public JsonResult GetAnswersFortab1(string exact) { string EnterpriseId = "User"; try { using(SqlConnection sqlcon = new SqlConnection(con)) { SqlCommand cmd = new SqlCommand("[PROC_NH_Journal_Tab1Data]", sqlcon); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@EnterpriseId", EnterpriseId); cmd.Parameters.AddWithValue("@exactgroup", exact); SqlDataAdapter adapter = new SqlDataAdapter(cmd); DataSet data = new DataSet(); adapter.Fill(data, "Table2"); DataTable dt1 = data.Tables["Table2"]; if(dt1.Rows.Count == 0) { // 日志记录,方便排查参数是否正确 System.Diagnostics.Debug.WriteLine($"No data found for EnterpriseId: {EnterpriseId}, Group: {exact}"); } ViewBag.getJson = dt1; return Json(dt1); } } catch(Exception ex) { System.Diagnostics.Debug.WriteLine($"Error: {ex.Message}"); throw; } }
内容的提问来源于stack exchange,提问作者Neeta
相关产品推荐
相关产品推荐

