0

I have a stored procedure in my database:

ALTER PROCEDURE [dbo].[SP_UPDATE_PARAMS]
    (@ELEMENT NUMERIC (10),
     @NUM_PARAM_OP_DINT NUMERIC (3,0) OUTPUT,
     @NUM_PARAM_OP_REAL NUMERIC (3,0) OUTPUT,
     @NUM_PARAM_LL NUMERIC (3,0) OUTPUT,
     .... + other 500 output params

The procedure produces an output for each value depending on what @Element value is. Otherwise it returns a value of 0.

So, in my C# code I try to use this:

....
using (SqlConnection connection = new SqlConnection(connectString))
{
    connection.Open();

    using (SqlCommand cmd = new SqlCommand("[dbo].[SP_UPDATE_PARAMS]", connection))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@ELEMENT", SqlDbType.Int).Value = element;

        SqlDataReader rdr = cmd.ExecuteReader();
.....

But I get this error:

Stored procedure or function [dbo].[SP_UPDATE_PARAMS] expects parameter which is not supplied @NUM_PARAM_OP_DINT

This will happen if I do not provide a value for each of the 504 values of [dbo].[SP_UPDATE_PARAMS] (even if they are output)

I tried using

foreach (IDataParameter param in cmd.Parameters)
{
    param.Value = DBNull.Value;
}

and

foreach (SqlParameter parameter in cmd.Parameters)
{
    parameter.Value = DBNull.Value;
}

before calling

SqlDataReader rdr = cmd.ExecuteReader();

but none of them will do, as cmd.Parameters are null until (I guess) cmd.ExecuteReader() is executed.

How could I avoid having to provide a value for all parameters, or make all of them be null?

3
  • 3
    Output doesn't mean that the parameter are created for you by the stored procedure. You still need to create them and then the stored procedure can set the values in each parameter for you to retrieve after executing the command Commented Nov 18, 2021 at 16:00
  • Side note: you should not use the sp_ prefix for your stored procedures. Microsoft has reserved that prefix for its own use (see Naming Stored Procedures), and you do run the risk of a name clash sometime in the future. It's also bad for your stored procedure performance. It's best to just simply avoid sp_ and use something else as a prefix - or no prefix at all! Commented Nov 18, 2021 at 18:05
  • 500 output parameters is a real code smell. Can they not be merged, or perhaps you should be returning a regular resultset using SELECT? Note also that if you create defaults for the parameters and do not pass them, SqlCommand will not return them Commented Nov 19, 2021 at 9:17

2 Answers 2

1

The cmd.Parameters property is empty and you add parameters to it for the procedure you're trying to execute.

https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.parameters?view=dotnet-plat-ext-6.0#property-value

You could create an object with an array of parameters for that stored procedure's parameters with defaults and pass that object in as your parameters. You can still set your @ELEMENT value this way as well.

https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlparametercollection.addrange?view=dotnet-plat-ext-6.0

Another potential solution, make your stored proc OUTPUT params optional

ALTER PROCEDURE [dbo].[SP_UPDATE_PARAMS](@ELEMENT NUMERIC (10),
                                                @NUM_PARAM_OP_DINT  NUMERIC (3,0) = NULL OUTPUT,
                                                @NUM_PARAM_OP_REAL  NUMERIC (3,0) = NULL OUTPUT,
                                                @NUM_PARAM_LL   NUMERIC (3,0) = NULL OUTPUT,
Sign up to request clarification or add additional context in comments.

2 Comments

So answer would be: It is not possible do so. Possible workarounds are: 1-) Initializing and passing values 2-) Modifying procedure to give default values. Thanks!
Without knowing more about what you're trying to do and the system you're working in those seem like the simplest options to work with that stored proc. If the SP is expecting the parameters, you'll have to provide them.
1

If you are passing a null parameter to a proc you need to declare the param as NULL such as

@ELEMENT NUMERIC (10) = NULL,
@NUM_PARAM_OP_DINT  NUMERIC (3,0) = NULL,
@NUM_PARAM_OP_REAL  NUMERIC (3,0) = NULL,
@NUM_PARAM_LL   NUMERIC (3,0) = NULL,

You will still need to provide the params to the proc but depending on what ones you actually want to be null pass a DBNull.Value

Edit: Do not use AddWithValue for the love of God. just use Add

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.