Skip to content

How to get output parameter and also a table when executing a stored procedure


  • I’m working with SQL Server 2017 (not possible to change)
  • I’m using Visual Studio 2019 in C# console and .NET Framework 4.5 (possible to change)
  • I’m using ADO.NET because several years before we couldn’t use Entity Framework, as the system is made to work with a stored procedure that returns at least 100k rows (possible to change)


I have an USP that returns a table that is at least 100k of rows by 20 fields. I need to add an output parameter in order to get also an ID created by the USP itself. So, the situation is that I need return a table and an ID (called ProcMonitorId). I don’t know if this is even so possible (See workarounds section)

At the SQL level is seems to be so far so good:

CREATE PROCEDURE [myschema].[mystore]
    @ProcMonitorId BIGINT OUTPUT

    SELECT fields FROM myTable

    SELECT @ProcMonitorId = @internalVariable

SQL execution:

enter image description here

And at repository layer (only relevant lines, someone were surprised for health of example):

var command = new SqlCommand("myStoreProcedure", mycon);
command.CommandType = CommandType.StoredProcedure;
SqlParameter outPutParameter = new SqlParameter();
outPutParameter.ParameterName = "@ProcMonitorId";
outPutParameter.SqlDbType = System.Data.SqlDbType.BigInt;
outPutParameter.Direction = System.Data.ParameterDirection.Output;

// Open connection etc-etc that works
SqlDataAdapter da = new SqlDataAdapter(command);
DataTable dt = new DataTable();
string ProcMonitorId = outPutParameter.Value.ToString();


Everything worked fine until the addition of the output at C# level. It returns in the line:

string ProcMonitorId = outPutParameter.Value.ToString();

it returns NullReferenceException because Value is null (that can’t be) and of course, can’t convert to String. I would solve this situation by adding a ? but if that’s situation happens for real, I need catch it any way as error. The main idea is that Value can not be null.

As I don’t have any ORM map, (and my expertise is not ADO.NET but Entity Framework) I can’t understand why is null (No, is not null at SQL layer, always return a value)


How can I solve this error or how can I return a BIGINT parameter and ALSO a table result?


As I first glance I have to solve it quickly, I made a:

SELECT 1 as type, @procID as procid, null as data1, null as data2
SELECT 2 as type, null as procid, data1, data2

in order to simulate a “header” and “data” rows on one single table. But I don’t like this solution and is not very elegant and flexible. I’ve to parse the header every time.

Thanks in advance and please comment anything, tip, help, workaround, I will be glade to update my answer if more information is needed.

Also I can make my Framework to .NET Core or change to Entity Framework. That I can’t change is my SQL version

Update #2
No changes in SQL – Still working as screenshot
In C# – Hangs out for ever

    SqlConnection connection = new SqlConnection(ConfigurationManager.AppSettings["DbConnection"]);

    var command = new SqlCommand("myUSP", connection);
    command.CommandType = CommandType.StoredProcedure;
    command.CommandTimeout = Convert.ToInt16(ConfigurationManager.AppSettings["DataBaseTimeOut"]);
    if (connection.State != ConnectionState.Open)

        SqlParameter r = command.Parameters.Add("@ProcMonitorId", SqlDbType.BigInt);
        r.Direction = ParameterDirection.Output;

        DataTable dt = new DataTable();
        using (var rdr = command.ExecuteReader())
            long id = (long)r.Value;

        SqlDataAdapter da = new SqlDataAdapter(command);




The parameter value won’t be available until after you consume the resultset, eg

var cmd0 = new SqlCommand("create or alter procedure pFoo @id int output as begin  select * from sys.objects; set @id = 12; end", con);

var cmd = new SqlCommand("pFoo", con);
cmd.CommandType = CommandType.StoredProcedure;

var p1 = cmd.Parameters.Add("@id", SqlDbType.Int);
p1.Direction = ParameterDirection.Output;

var dt = new DataTable();
using (var rdr = cmd.ExecuteReader())
    var id = (int)p1.Value;
User contributions licensed under: CC BY-SA
9 People found this is helpful