【问题标题】:Stored Procedure is returning number of rows instead of column values存储过程返回行数而不是列值
【发布时间】:2017-12-22 05:23:53
【问题描述】:

我正在从 ASP.NET 调用存储过程来获取一些数据以存储在数组中。问题是为了返回我需要的值,我首先必须调用另一个存储过程并将结果转储到临时表中。这会在 SQL 端生成正确的记录,但是当我在 ASP 中调用它时,它会将最后一条记录的索引作为 int 返回。因此,即使 SQL 生成正确的结果,ASP 在调用存储过程时也无法访问它们。

我的 SQL 设置如下:

IF OBJECT_ID('#temp') IS NOT NULL
    BEGIN
        DROP TABLE #temp
    END

CREATE TABLE #temp 
(
EventID nvarchar(50),
RunDate date,
SectionCode nvarchar(50),
SectionMapCode nvarchar(50),
DispSort int,
Capacity nvarchar(50),
Attendance int,
PctCap int,
HeatColor nvarchar(50)
)

DECLARE @runDate date = GETDATE()
--Insert results from killsheet sproc into temp table
INSERT #temp  Exec GameDayReporting.dbo.uspGetEventKillSheetDetailedReport @EventID, @runDate;

select Capacity from #temp;

SQL 输出:

ASP 调用:

string option = TempData["option"].ToString();
var secCapacity = db.uspGetSecCapacityNew(option);
ViewData["Capacity"] = secCapacity;
System.Diagnostics.Debug.WriteLine("capacity " + secCapacity);

以及 ASP 输出:

capacity 261

注意secCapacity 如何等于 261​​,这是 SQL 结果中的最后一个行号。

那么我如何访问实际的查询结果而不是数据的大小?

【问题讨论】:

  • 存储过程返回的是行数,不是结果集。 db 这里是什么?这是实体框架吗?
  • 正确,如何获取结果集? Select From 应该可以正常工作,不是吗?
  • 您需要在存储过程的顶部添加set nocount on 吗?
  • 您需要将存储过程作为函数导入。看看这里stackoverflow.com/questions/32140774/…
  • @DaveShaw 打得好...

标签: c# asp.net sql-server entity-framework tsql


【解决方案1】:

我能够通过从 ASP 中分离我的存储过程而不是尝试从 SQL 导入特定数据来解决它。

    var uspCapacity = from d in db.uspGetEventKillSheetDetailedReport(option, date)
                      select new
                      {
                          d.Capacity
                      };
    var uspAttendance = from d in db.uspGetEventKillSheetDetailedReport(option, date)
                        select new
                        {
                            d.Attendance
                        };
    var uspSectionMapCode = from d in db.uspGetEventKillSheetDetailedReport(option, date)
                        select new
                        {
                            d.SectionMapCode
                        };

    var uspCapacityList = uspCapacity.ToArray();
    var uspAttendanceList = uspAttendance.ToArray();
    var uspSectionMapCodeList = uspSectionMapCode.ToArray();

我测试过:

    for (var i = 0; i < 3; i++)
    {
        System.Diagnostics.Debug.WriteLine("Capacity " + uspCapacityList[i] + " Attendance " + uspAttendanceList[i] + " Section Map Code " + uspSectionMapCodeList[i]);
    }

【讨论】:

    【解决方案2】:

    无意冒犯,但您似乎添加了一层不需要存在的复杂性。本节:

    DECLARE @runDate date = GETDATE()
    --Insert results from killsheet sproc into temp table
    INSERT #temp  Exec GameDayReporting.dbo.uspGetEventKillSheetDetailedReport @EventID, @runDate;
    
    select Capacity from #temp;
    

    您正在使用单个 proc 插入 SQL Server 中的临时对象。为什么不只返回那个依赖的过程?这是一个非常占用内存的内存操作还是需要临时存储的东西?如果不是,我只会得到结果集。兼顾临时存储和返回结果集可能会出现问题。尤其是当您处理 .NET 层处理的返回时:

    1. 动态 SQL
    2. tempdb 中的临时存储(# 或 ## 表)

    除非你有一些严格的规则,否则我只会用你的返回数据来处理

    GameDayReporting.dbo.uspGetEventKillSheetDetailedReport @EventID, @runDate
    

    如果您使用的是实体框架,则包装一个 Poco 对象列表;如果您使用的是 ADO.NET,则包装一个 DataTable。

    【讨论】:

    • 好吧,我们使用的是临时表,因为我们需要一次隔离一列。 uspGetEventKillSheetDetailedReport 有 5-6 列我们不需要,所以我们的计划是查询 uspGetEventKillSheetDetailedReport 以获取我们需要的列,将其存储到临时表中,然后查询临时表,因为我们不能查询一个存储过程。
    • 您可以将数据保存在内存中以供以后查询,或者如果您要在市场分析后进行,请使用永久表。我不会将数据存储在您稍后将要返回的 tempdb 中。它通常用于临时存储,因此得名。如果您确实想从临时对象返回,但想稍后查询该对象本身,为什么不创建一个永久表并将其标记为类似于:'stagingKillSheetDetailedReport'?您将在分析 tempdb 对象时遇到麻烦。这是通常为 SQL Server 保留的级别,而不是 .NET 访问。
    • 我想使用 temp 因为如果我们使用永久数据库,每次有人运行程序时,它都会在表中生成 261 个更多条目(我正在为 3 个查询执行此操作)所以它会得到记忆力真的很强烈。我们找到了一种方法来代替使用from d in ...... select new {d.capacity} 之类的东西。我会尽快发布答案
    • 嗯,每次运行此过程时,您都会删除表。因此,它被丢弃是有道理的,但是 x 多次调用它,并且您可以在 z 次得到 y 结果。我只是说 tempdb 是临时的。如果您害怕重复插入某个区域以便稍后获取数据,您可以轻松地运行合并语句或其他条件逻辑。
    猜你喜欢
    • 1970-01-01
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 2017-07-12
    • 1970-01-01
    • 2019-12-29
    相关资源
    最近更新 更多