SQLite REAL错误

时间:2014-05-05 17:09:24

标签: sqlite

我在使用SQLite时遇到了一些麻烦。我曾经把“时间”保存为一个int,但我现在想把它作为一个double,这会导致一些问题。我每次尝试新修复时都会重新创建数据库,但它没有任何效果。每当我尝试保存时,它都会收到错误“3列的4个值”。当我把它全部改回int时,它再次正常工作。此外,如果我只是从保存过程中删除“所有togeater的时间,我得到错误”3列的2个值“。我不知道发生了什么。是否真的占用两个值或什么交易?

创建表格:

            sql = "CREATE TABLE Speed (id INTEGER PRIMARY KEY AUTOINCREMENT, LanguageType VARCHAR(20), cardsetNumber INT, time REAL)";
        command = new SQLiteCommand(sql, dbConnection);
        command.ExecuteNonQuery();

添加到表格中:

    public void SaveSpeed(int cardsetNumber, LanguageType lt, double time)
    {
        Open();
        sql = "insert into Speed (cardsetNumber, LanguageType, time) values (" + cardsetNumber + ", '" + lt + "', " + time + ")";
        command = new SQLiteCommand(sql, dbConnection);
        command.ExecuteNonQuery();
        Close();
    }

1 个答案:

答案 0 :(得分:1)

根据Wikipedia,丹麦使用逗号作为小数分隔符。最有可能的是,您的流程的默认文化是丹麦语,在将十进制数转换为字符串时会强制使用小数点分隔符。

你正在做两件事,你不应该在你的代码中做,但在这种情况下,更改一个将解决问题:

  • 您可以将值转换为基于不是invariant culture的区域性的字符串,而不是将其显示给用户。
  • 您正在通过将未转义的值连接到查询字符串中来构建具有自定义值的SQL查询。

第一个意味着不希望读取特定于语言环境的数字格式的代码将简单地解释您的字符串与预期不同。特别是,当读取另一台机器上的字符串(具有另一个默认语言环境集)时也是如此,但在这种情况下,它只是因为SQL解析器从不期望任何特定于语言环境的数字格式(并且,因为逗号服务)作为参数分隔符,语法实际上将停止定义良好,除非解析器将添加任何进一步的特定于语言环境的修订。)

第二种情况可能会导致really bad trouble,因此您最好总是避免使用它。


那么,这里发生了什么?通过特定于语言环境的转换,时间数转换为类似 1,2 的内容,SQL解析器将其解释为两个整数(用逗号分隔) ,而不是一个十进制数。因此有关参数计数的错误消息。


当结果针对的是程序而不是人类时,可以通过明确指定字符串转换的不变文化来解决第一个问题。当您或其他人打算将值读回数字类型时,始终执行此操作,例如,将其以基于文本的格式存储为CSV或XML等计算机时。

至于第二个问题,要将任何自定义(文字)值插入到SQL查询中(特别是,但不是唯一的,那些在某处未经硬编码但从用户输入接收的值),请对查询字符串进行参数化:

sql = "insert into Speed (cardsetNumber, LanguageType, time) values (@cardsetNumber, @lt, @time)";
command = new SQLiteCommand(sql, dbConnection);
command.Parameters.AddWithValue("@cardsetNumber", cardsetNumber);
command.Parameters.AddWithValue("@lt", lt);
command.Parameters.AddWithValue("@time", time);

这将自动在文字值中插入任何引号或转义标记,并且不存在有意或无意的风险SQL injection