The parameterized query ..... expects the parameter '@units', which was not supplied

C#Sql ServerException

C# Problem Overview


I'm getting this exception:

> The parameterized query '(@Name nvarchar(8),@type nvarchar(8),@units nvarchar(4000),@rang' expects the parameter '@units', which was not supplied.

My code for inserting is:

public int insertType(string name, string type, string units = "N\\A", string range = "N\\A", string scale = "N\\A", string description = "N\\A", Guid guid = new Guid())
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        SqlCommand command = new SqlCommand();
        command.CommandText = "INSERT INTO Type(name, type, units, range, scale, description, guid) OUTPUT INSERTED.ID VALUES (@Name, @type, @units, @range, @scale, @description, @guid) ";
        command.Connection = connection;
        command.Parameters.AddWithValue("@Name", name);
        command.Parameters.AddWithValue("@type", type);
        command.Parameters.AddWithValue("@units", units);
        command.Parameters.AddWithValue("@range", range);
        command.Parameters.AddWithValue("@scale", scale);
        command.Parameters.AddWithValue("@description", description);
        command.Parameters.AddWithValue("@guid", guid);
        return (int)command.ExecuteScalar();
    }
}

The exception was a surprise because I'm using the AddWithValue function and making sure I added a default parameters for the function.

SOLVED:

The problem was that the some parameters where empty Strings (that override the default)

This is the working code:

public int insertType(string name, string type, string units = "N\\A", string range = "N\\A", string scale = "N\\A", string description = "N\\A", Guid guid = new Guid())
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
            SqlCommand command = new SqlCommand();
            command.CommandText = "INSERT INTO Type(name, type, units, range, scale, description, guid) OUTPUT INSERTED.ID VALUES (@Name, @type, @units, @range, @scale, @description, @guid) ";
            command.Connection = connection;
            command.Parameters.AddWithValue("@Name", name);
            command.Parameters.AddWithValue("@type", type);

            if (String.IsNullOrEmpty(units))
            {
                command.Parameters.AddWithValue("@units", DBNull.Value); 
            }
            else
                command.Parameters.AddWithValue("@units", units);
            if (String.IsNullOrEmpty(range))
            {
                command.Parameters.AddWithValue("@range", DBNull.Value);
            }
            else
                command.Parameters.AddWithValue("@range", range);
            if (String.IsNullOrEmpty(scale))
            {
                command.Parameters.AddWithValue("@scale", DBNull.Value);
            }
            else
                command.Parameters.AddWithValue("@scale", scale);
            if (String.IsNullOrEmpty(description))
            {
                command.Parameters.AddWithValue("@description", DBNull.Value);
            }
            else
                command.Parameters.AddWithValue("@description", description);
            
            
            
            
            command.Parameters.AddWithValue("@guid", guid);


            return (int)command.ExecuteScalar();
        }
        
        
    }

C# Solutions


Solution 1 - C#

Try this code:

SqlParameter unitsParam = command.Parameters.AddWithValue("@units", units);
if (units == null)
{
    unitsParam.Value = DBNull.Value;
}

And you must check all other parameters for null value. If it null you must pass DBNull.Value value.

Solution 2 - C#

Here's a way using the null-coalescing operator:

cmd.Parameters.AddWithValue("@units", units ?? (object)DBNull.Value);
cmd.Parameters.AddWithValue("@range", range ?? (object)DBNull.Value);
cmd.Parameters.AddWithValue("@scale", scale ?? (object)DBNull.Value);
cmd.Parameters.AddWithValue("@description", description ?? (object)DBNull.Value);

Or for more strict type checking:

cmd.Parameters.Add("@units", SqlDbType.Int).Value = units ?? (object)DBNull.Value;
cmd.Parameters.Add("@range", SqlDbType.Int).Value = range ?? (object)DBNull.Value;
cmd.Parameters.Add("@scale", SqlDbType.Int).Value = scale ?? (object)DBNull.Value;
cmd.Parameters.Add("@description", SqlDbType.VarChar).Value = description ?? (object)DBNull.Value;

The operator also be chained:

int?[] a = { null, null, 1 };
Console.WriteLine(a[0] ?? a[1] ?? a[2]);

Solution 3 - C#

This extension class was useful to me a couple of times so far, for those issues:

public static class DbValueExtensions
{
	// Used to convert values coming from the db
	public static T As<T>(this object source)
	{
		return source == null || source == DBNull.Value
			? default(T)
			: (T)source;
	}

	// Used to convert values going to the db
	public static object AsDbValue(this object source)
	{
		return source ?? DBNull.Value;
	}
}

You would normally use it in two scenarios. First, when creating parameters for your query:

var parameters = new Dictionary<string, object>
{
	{ "@username", username.AsDbValue() },
	{ "@password", password.AsDbValue() },
	{ "@birthDate", birthDate.AsDbValue() },
};

or when parsing the SqlReader values:

while (reader.Read())
{
	yield return new UserInfo(
		reader["username"].As<string>(),
		reader["birthDate"].As<DateTime>(),
		reader["graduationDate"].As<DateTime?>(),
		reader["nickname"].As<string>()
	);
}

Solution 4 - C#

command.Parameters.AddWithValue("@Name", (name == null ? "" : name));

Solution 5 - C#

This is a method to be reused with multiple parameters:

public void NullorEmptyParameter(QC.SqlCommand command, string at, string value)
{
    if (String.IsNullOrEmpty(value))
    {
        command.Parameters.AddWithValue(at, DBNull.Value);
    }
    else
        command.Parameters.AddWithValue(at, value);
}

And then you can reuse it for as many commands and params:

NullorEmptyParameter(command, "@Idea_ID", Idea_ID);
NullorEmptyParameter(command, "@Opportunities_or_Idea", Opportunities_or_Idea);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYogevnnView Question on Stackoverflow
Solution 1 - C#DenisView Answer on Stackoverflow
Solution 2 - C#WillView Answer on Stackoverflow
Solution 3 - C#Mladen B.View Answer on Stackoverflow
Solution 4 - C#SaadView Answer on Stackoverflow
Solution 5 - C#locnguyenView Answer on Stackoverflow