尽管有足够的参数,SQLite 仍显示“提供给命令的参数不足”

Posted

技术标签:

【中文标题】尽管有足够的参数,SQLite 仍显示“提供给命令的参数不足”【英文标题】:SQLite showing "Insufficient Parameters supplied to the command" despite having enough parameters 【发布时间】:2021-12-11 12:29:14 【问题描述】:

我有以下 SQLite 表。

CREATE TABLE "Ingredient_Detailed" (
    "DETAILED_INGREDIENT_ID"    TEXT,
    "INGREDIENT_CODE"   INTEGER NOT NULL,
    "BRAND" TEXT NOT NULL,
    "INGREDIENT_SOURCE" TEXT NOT NULL,
    "UNIT_PRICE"    REAL NOT NULL DEFAULT 0,
    "AMOUNT_IN_UNIT"    REAL NOT NULL DEFAULT 0,
    "MINIMUM_PRICE_PER_UNIT"    REAL NOT NULL DEFAULT 0,
    "QUALITY"   INTEGER NOT NULL DEFAULT 1,
    "UNITS_AVAILABLE"   INTEGER NOT NULL DEFAULT 0,
    FOREIGN KEY("INGREDIENT_CODE") REFERENCES "Ingredient"("CODE"),
    PRIMARY KEY("DETAILED_INGREDIENT_ID")
)

我有一个 C# 应用程序,我尝试使用以下方法将记录插入此表:

public int SaveDetailedIngredient(DetailedIngredient pDetailedIngredient)
    
        try
        
            using (var conn = new SQLiteConnection(GetConnectionString()))
            
                var saveDetailedIngredientCommand = new SQLiteCommand("INSERT INTO INGREDIENT_DETAILED (DETAILED_INGREDIENT_ID, " +
                    "INGREDIENT_CODE, BRAND, INGREDIENT_SOURCE, UNIT_PRICE, AMOUNT_IN_UNIT, " +
                    "MINIMUM_PRICE_PER_UNIT, QUALITY, UNITS_AVAILABLE) " +
                    "VALUES ($pDetailedIngredientId, $pCode, $pBrand, $pSource, $pUnitPrice, $pAmountInUnit, $pPricePerUnit, $pQuality, $pUnitsAvailable)", conn);
                pDetailedIngredient.DetailedIngredientCode = pDetailedIngredient.Code + "-" + pDetailedIngredient.Brand + "-" + pDetailedIngredient.IngredientSource;
                saveDetailedIngredientCommand.Parameters.AddWithValue("pDetailedIngredientId", pDetailedIngredient.DetailedIngredientCode);
                saveDetailedIngredientCommand.Parameters.AddWithValue("pCode", pDetailedIngredient.Code);
                saveDetailedIngredientCommand.Parameters.AddWithValue("pBrand", pDetailedIngredient.Brand.Trim().ToUpper());
                saveDetailedIngredientCommand.Parameters.AddWithValue("pSource", pDetailedIngredient.IngredientSource.Trim().ToUpper());
                saveDetailedIngredientCommand.Parameters.AddWithValue("pUnitPrice,", pDetailedIngredient.UnitPrice);
                saveDetailedIngredientCommand.Parameters.AddWithValue("pAmountInUnit", pDetailedIngredient.AmountInUnit);
                saveDetailedIngredientCommand.Parameters.AddWithValue("pPricePerUnit", pDetailedIngredient.MinimumUnitPrice);
                saveDetailedIngredientCommand.Parameters.AddWithValue("pQuality", pDetailedIngredient.Quality);
                saveDetailedIngredientCommand.Parameters.AddWithValue("pUnitsAvailable", pDetailedIngredient.UnitsAvailable);

                conn.Open();
                return saveDetailedIngredientCommand.ExecuteNonQuery();

            
        
        catch (SQLiteException sqlEx)
        

            Console.WriteLine(sqlEx.Message);
            Console.WriteLine(sqlEx.ErrorCode);
            throw sqlEx;
        
        catch (Exception ex)
        
            Console.WriteLine(ex.Message);
            throw ex;
        
    

尽管指示了 9 个字段并提供了 9 个参数,但 SQLite 会抛出异常“未知错误:提供给命令的参数不足”。

我复制并粘贴了参数的名称以确保它们没有错字,但它仍然会引发错误。

我在方法执行期间调试了应用程序,提供的pDetailedIngredient 分配了所有必要的属性值,我可以看到命令中的每个参数都被正确分配。

我还有其他几种向其他表插入数据的方法,都遵循相同的结构,所以我怀疑这与我的方法的编写方式有关。

我在这里遗漏了什么吗?感觉这不是正确的错误。

【问题讨论】:

请在执行开始前在“saveDetailedIngredientCommand”中发布您所拥有的内容 我注意到文档中的示例也将 $ 放入传递给 AddWithValue 的参数名称中 @CaiusJard 是正确的。 “$”是参数名称的一部分。添加到集合中时分配给每个参数的名称应包含“$”。 @Mark Benningfield ...我同意它应该只是为了可读性而匹配,但是从文档中...Parameters ... “参数可以以:、@或$作为前缀。” ...我通常会以“@”字符为前缀,而其他两个不知道。另外,在我的小测试中,我尝试了在参数定义中使用/不使用前缀,它在“AddWithValue”中没有任何区别......同样的错误。在我的解决方案中,它也没有任何区别......它可以使用/不使用前缀。奇怪…… 好吧,在不知道 OP 使用的是哪个特定的 C# 绑定的情况下,此时无话可说。 【参考方案1】:

老实说,我真希望我能很好地回答“为什么”会发生这种情况。我只能假设“AddWithValue”正在做一些我不知道的事情。但是,经过一番反复,我会请您尝试一下,看看它是否对您有用。

我改变的是通过添加如下所示的参数。这始终适用于一些测试,并且仅在 id 重复时才按预期失败。请让我知道这是否对您有帮助,因为从某种意义上说,从表面上看,您的代码对我来说看起来不错。

saveDetailedIngredientCommand.Parameters.Add("pDetailedIngredientId", DbType.String).Value = pDetailedIngredient.DetailedIngredientCode;
saveDetailedIngredientCommand.Parameters.Add("pCode", DbType.Int32).Value = pDetailedIngredient.Code;
saveDetailedIngredientCommand.Parameters.Add("pBrand", DbType.String).Value = pDetailedIngredient.Brand.Trim().ToUpper();
saveDetailedIngredientCommand.Parameters.Add("pSource", DbType.String).Value = pDetailedIngredient.IngredientSource.Trim().ToUpper();
saveDetailedIngredientCommand.Parameters.Add("pUnitPrice", DbType.Decimal).Value = pDetailedIngredient.UnitPrice;
saveDetailedIngredientCommand.Parameters.Add("pAmountInUnit", DbType.Decimal).Value = pDetailedIngredient.AmountInUnit;
saveDetailedIngredientCommand.Parameters.Add("pPricePerUnit", DbType.Decimal).Value = pDetailedIngredient.MinimumUnitPrice;
saveDetailedIngredientCommand.Parameters.Add("pQuality", DbType.Int32).Value = pDetailedIngredient.Quality;
saveDetailedIngredientCommand.Parameters.Add("pUnitsAvailable", DbType.Int32).Value = pDetailedIngredient.UnitsAvailable;

如果这对你不起作用,请告诉我,我会删除它。

【讨论】:

这行得通。谢谢你。所以这似乎是 AddWithValue 方法的一个错误。我相信这与十进制字段特别相关。 SQLite 实际上没有数据类型,它有相似性,但它都是引擎盖下的文本。我的猜测是 AddWithValue 无法正确从 c# 十进制转换为 SQLite real 确认问题是由小数字段引起的。即使在使用 AddWithValue 时,删除这些字段也会使该方法按预期工作

以上是关于尽管有足够的参数,SQLite 仍显示“提供给命令的参数不足”的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js:尽管有条件渲染,元素仍会显示片刻

尽管存在符号链接,ld 仍无法加载库

尽管已正确初始化,XIB 视图仍不显示任何内容

函数调用报告尽管传递了有效参数,但仍给出了 0 个参数

尽管视图初始化,有时仍会显示已删除的项目-Vue,Node.js [重复]

尽管付款转账成功,Paypal 仍显示错误消息