在不为参数提供值的情况下执行 SqlCommand

Execute SqlCommand without providing values to parameters

我的数据库中有一个存储过程:

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

该过程根据 @Element 值是什么为每个值生成一个输出。否则它 returns 值为 0。

所以,在我的 C# 代码中,我尝试使用这个:

....
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();
.....

但是我得到这个错误:

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

如果我不为 [dbo].[SP_UPDATE_PARAMS] 的 504 个值中的每一个提供值(即使它们是输出),也会发生这种情况

我试过使用

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

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

调用前

SqlDataReader rdr = cmd.ExecuteReader();

但其中 none 会起作用,因为 cmd.Parameters 为空,直到(我猜)cmd.ExecuteReader() 被执行。

我怎样才能避免必须为所有参数提供一个值,或者让所有参数都为空?

如果将空参数传递给 proc,则需要将参数声明为 NULL,例如

@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,

您仍然需要向 proc 提供参数,但取决于您实际希望哪些参数为 null 通过 DBNull.Value

编辑:看在上帝的份上不要使用AddWithValue。只需使用 Add

cmd.Parameters 属性 为空,您为要执行的过程添加了参数。

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

您可以为具有默认值的存储过程的参数创建一个包含参数数组的对象,并将该对象作为您的参数传入。您仍然可以通过这种方式设置您的@ELEMENT 值。

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

另一种可能的解决方案,使您的存储过程输出参数可选

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,