参数化查询.....需要未提供的参数“@units”

Posted

技术标签:

【中文标题】参数化查询.....需要未提供的参数“@units”【英文标题】:The parameterized query ..... expects the parameter '@units', which was not supplied 【发布时间】:2014-06-20 08:01:03 【问题描述】:

我遇到了这个异常:

参数化查询 '(@Name nvarchar(8),@type nvarchar(8),@units nvarchar(4000),@rang' 需要参数 '@units',但未提供。

我的插入代码是:

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

这个异常令人惊讶,因为我使用了AddWithValue 函数并确保我为该函数添加了默认参数。

已解决:

问题在于某些参数为空字符串(覆盖默认值)

这是工作代码:

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


    

【问题讨论】:

您忘记将@ 作为每个参数名称的第一个字符。 @AndrewMorton:为什么错误信息是抱怨@units而不是@Name,这是最先出现的? @O.R.Mapper 我想它不必按照提供的顺序查找它们。 我很震惊,因为仍然没有人回答这个问题。顺便说一句,2 点赞? @AndrewMorton 我添加了 @ 并且仍然是相同的异常 【参考方案1】:

试试这个代码:

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

    unitsParam.Value = DBNull.Value;

并且您必须检查所有其他参数的空值。如果它为 null,则必须传递 DBNull.Value 值。

【讨论】:

我不认为它可以为空,因为 OP 有这样的参数string units = "N\\A" 可以,因为你可以像这样调用方法insertType(null, null, null, null, null, null); 问题解决了!我将使用解决方案编辑我的消息。谢谢大家! @GrantWinney 显然这不是它的工作原理。该参数必须从调用代码中省略,而不是设置为null。 Named and Optional Arguments 写这个的更短的方式是command.Parameters.AddWithValue("@units", (object)units ?? DBNull.Value)【参考方案2】:

这是使用空合并运算符的一种方法:

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

或者更严格的类型检查:

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;

操作符也被链接起来:

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

【讨论】:

【参考方案3】:

到目前为止,这个扩展类对我有用几次,对于这些问题:

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;
    

您通常会在两种情况下使用它。首先,在为您的查询创建参数时:

var parameters = new Dictionary<string, object>

     "@username", username.AsDbValue() ,
     "@password", password.AsDbValue() ,
     "@birthDate", birthDate.AsDbValue() ,
;

或在解析 SqlReader 值时:

while (reader.Read())

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

【讨论】:

【参考方案4】:
command.Parameters.AddWithValue("@Name", (name == null ? "" : name));

【讨论】:

【参考方案5】:

这是一个多参数复用的方法:

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

然后您可以将它重复用于尽可能多的命令和参数:

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

【讨论】:

以上是关于参数化查询.....需要未提供的参数“@units”的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET C# SQL 提交错误

MySQL 参数化查询的功能就像它在 C# 应用程序中未参数化一样

什么是参数化查询?

需要 xxxxxx 类型的参数,但未提供

AWS Athena - 如何参数化 SQL 查询

基于参数选择的单个查询(如果或未提供)