I have the following stored procedure:
/****** Object: StoredProcedure [dbo].[OpsToolStats] Script Date: 09/05/2023
09:21:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author, , Name>
-- Create Date: <Create Date, , >
-- Description: <Description, , >
-- =============================================
ALTER PROCEDURE [dbo].[OpsToolStats]
(
-- Add the parameters for the stored procedure here
@startDate datetime,
@endDate datetime
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
SELECT count([EndCustomerOrderId]) AS NewOrdersNeedsLabels
FROM [dbo].[EndCustomerOrders]
where ([StatusId] = 0 or [StatusId] = 1000) and CreatedAt >= @startDate and [CreatedAt]
<= @endDate
SELECT count([EndCustomerOrderId]) AS APIErrorCeatingLabels
FROM [dbo].[EndCustomerOrders]
where [StatusId] = 1100 and CreatedAt >= @startDate and [CreatedAt] <= @endDate
SELECT count([EndCustomerOrderId]) AS ScheduleCollection
FROM [dbo].[EndCustomerOrders]
where ([StatusId] = 1300 or [StatusId] = 1500 or [StatusId] = 1700) and CreatedAt >=
@startDate and [CreatedAt] <= @endDate
END
In SQL Enterprise manager the results visually look like this:
I am trying to work out how to call this SP and get the results of the individual select statements:
I have the following code:
var command = _dbLive.Database.GetDbConnection().CreateCommand();
command.CommandText = "OpsToolStats";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@startDate", "2023-05-01"));
command.Parameters.Add(new SqlParameter("@endDate", "2023-05-31"));
_dbLive.Database.OpenConnection();
using var result = command.ExecuteReader();
var dataTable = new DataTable();
dataTable.Load(result);
But I only get 1 column and 1 row in the datatable... for the "NewOrdersNeedsLabels"..
Can anyone suggest how to get all the values please?
2条答案
按热度按时间i1icjdpr1#
You're using
DataTable.Load
which only loads the first resultset - it will ignore subsequent resultsets.Instead, use a
DataSet
object (which itself contains multipleDataTable
objects: one for each resultsset): asDataSet.Load
will attempt to consume all resultsets from aDbDataReader
for you.If you're using
SqlDataReader
directly (instead of lettingDataTable.Load
,DataSet.Load
orSqlDataAdapter
do all the hard work for you) then you will need to callNextResult()
after you finish yourwhile( rdr.Read() )
loop for the first result-set - and then have separatewhile( rdr.Read() )
loops for all expected subsequent results.It is important that you always check if
NextResult()
returnstrue
orfalse
and put the effort in to gracefully handle unexpecedly fewer actualk resultsets (this can happen if yourPROCEDURE
or statement-batch errors out.So this, basically:
Also:
Always specify exact
SqlDbType
values for everySqlParameter
because ADO.NET's type-inference is unhelpfully simplistic.Where-possible (i.e. on .NET 7+ with the latest
Microsoft.Data.SqlClient
library) when using SQL Server'sdate
for parameters you should use .NET'sDateOnly
value type instead ofDateTime
- and especially not date-string-literals - your current code as-is right now could potentially misbehave if thread culture/localization settings align with the stars.chy5wohz2#
many thanks for the pointers.. this is what i ended up with: