0

In my Create method, I am using a stored procedure to INSERT INTO my SQL Server database. Sometimes, fields such as Comment will be left blank. However, it does not work as I wished.

Firstly, this is how my method looks like:

using (SqlConnection connection = new SqlConnection(connectionString))
        {
            string sql = "CreateTask";

            using (SqlCommand command = new SqlCommand(sql, connection))
            {
                command.CommandType = CommandType.StoredProcedure;

                .....................

                parameter = new SqlParameter
                {
                    ParameterName = "@Condition",
                    Value = task.Condition,
                    SqlDbType = SqlDbType.NVarChar
                };
                command.Parameters.Add(parameter);
                .....................

When task.Condition is null, command.ExecuteNonQuery(); gets the following error:

: 'Procedure or function 'CreateTask' expects parameter '@Condition', which was not supplied.'

However, the columns in the table are set to allow null values.

enter image description here

The stored procedure also looks like this:

    ALTER PROCEDURE [dbo].[CreateTask]
    @Name        NVARCHAR(50),
    @IsGate   BIT,
    @Condition Varchar(450),
    @Precondition       Varchar(450),
    @Comments       Varchar(450),
    @StartDate       DateTime,
    @EndDate       DateTime,
    @AssignedTo    Nvarchar(450),
    @PhaseId int 
AS
BEGIN
    Insert Into dbo.Tasks (Name, IsGate, Condition, Precondition, Comments, StartDate, EndDate, AssignedTo, PhaseId, InProgress, Finished, Aborted) Values (@Name, @IsGate, @Condition, @Precondition, @Comments, @StartDate, @EndDate, @AssignedTo, @PhaseId, '0', '0', '0')
END

Therefore, what should I tweak in order to allow the stored procedure to get null values?

Questieme
  • 913
  • 2
  • 15
  • 34
  • 1
    Declare stored procedure's parameters as optional. [For reference](https://stackoverflow.com/questions/3415582/how-can-i-use-optional-parameters-in-a-t-sql-stored-procedure) – Yurii Dec 21 '19 at 14:58
  • If the value of the data is null you can assign `DBNull.Value` instead. – Crowcoder Dec 21 '19 at 14:58
  • @Crowcoder If I use, for example, `command.Parameters.Add(parameter, DBNull.Value);`, I get an error saying `cannot convert from System.DBNull to System.Data.SqlDbType` – Questieme Dec 21 '19 at 15:01
  • @Questieme so don't use that overload, do it exactly like in your example where you set `Value`. – Crowcoder Dec 21 '19 at 15:02
  • @Crowcoder Oh, silly me. I edited the code to this: `DBNull.Value = task.Condition` and now the error I'm getting is: `a static readonly field cannot be assigned to` , `invalid initializer member declarator` – Questieme Dec 21 '19 at 15:05
  • 1
    Declare the parameter as `@Condition varchar(450) = null`, if you don't add the parameter with `command.ParametersAdd` than it will be NULL. – Luuk Dec 21 '19 at 15:07
  • You can use a single statement to create the parameter, add it to the `Parameters` collection and set the value while converting C# `null` to SQL `null` as needed: `command.Parameters.Add("@Condition", System.Data.SqlDbType.VarChar, 450).Value = task.Condition ?? (object)DBNull.Value;`. – HABO Dec 21 '19 at 15:39

2 Answers2

2

Try this to assign DBNull.Value to the SqlParameter if the data is null and you want to insert null into the database:

parameter = new SqlParameter
{
    ParameterName = "@Condition",
    Value = (object)task.Condition ?? DBNull.Value,
    SqlDbType = SqlDbType.NVarChar
};
Crowcoder
  • 11,250
  • 3
  • 36
  • 45
  • a 'default', or optional parameter as @Yurii suggested is much better! – Luuk Dec 21 '19 at 15:08
  • `Operator '??' cannot be applied to operands of type 'string' and 'DBNull'` – Questieme Dec 21 '19 at 15:09
  • @Luuk not necessarily. You can't assume you always want a default on a stored procedure parameter. – Crowcoder Dec 21 '19 at 15:09
  • @Crowcoder: that's why you only specify it when it's needed.(it the parameter IS optional) – Luuk Dec 21 '19 at 15:10
  • 1
    @Questieme appologies, I forgot to cast to object. You could also set it outside if that looks too hacky. – Crowcoder Dec 21 '19 at 15:11
  • @Luuk I stand by my original comment, it may not be appropriate to allow blind nulls, you might want callers to be explicit. – Crowcoder Dec 21 '19 at 15:13
  • 1
    @Questieme as also noted you could set the default in the stored procedure itself but only you can know if that is what you want to happen. It has the advantage of not needing a code change. – Crowcoder Dec 21 '19 at 15:14
-1

If Condition , data type is used as string in C#, then while passing this parameter as null to the procedure will give this error.

So better to user some ternary operator like this

 com.Parameters.Add("@Condition", SqlDbType.VarChar).Value =                         
                    (object.Condition== null) ? string.Empty : object.Condition;

I was also facing the same issue, but DB.Null did not work in my case.

My case is like:

 com.Parameters.Add("@RentalCounterProduct1EquipmentCode", SqlDbType.VarChar).Value =                         
                    (obgKafkaStagingRentalSource.RentalCounterProduct1EquipmentCode == null) ? string.Empty : obgKafkaStagingRentalSource.RentalCounterProduct1EquipmentCode;
buddemat
  • 4,552
  • 14
  • 29
  • 49
  • The op wants to insert a NULL into the db. This will insert an empty string instead. As a rule, if a db column supports null, null should be used, not empty string. The absence of something is different from empty string in comparison as well as db optimizations. – ClearlyClueless Feb 12 '23 at 13:54