对于NUMERIC列,soci并不总是返回相同的类型

时间:2013-07-26 08:01:25

标签: sqlite soci

我使用soci库访问sqlite3数据库:

rowset<row> rs = (sql.prepare << "select * from my_table");
for (auto it = rs.begin(); it != rs.end(); ++it) {
    int some_value = it->get<int>(1);
    // ...
}

(这不是我的实际代码;描述问题时大大简化了。)

现在,大多数时候,这都有效。但是,有时,行中索引1处的值是字符串,而不是int(导致std::bad_cast异常)。相应列的SQL类型为NUMERIC(8) NOT NULL。我做了一些调试,它看起来像行中的条目数和它们的值总是正确的。唯一的问题是这一行的值有时是一个字符串。

这可能是社交中的错误,也可能是我方面的错误假设。我的假设是列的返回数据类型始终相同。类型切换可能在我的应用程序的一次运行中发生 - 值可能是一个查询结果中的int和下一个中的字符串。

由于我不知道底层的sqlite3 API,我甚至不确定这个问题是源于sqlite3还是社交。解决方法似乎很简单:检查行值的类型,如果是字符串,则将其转换为int。但重要的是要知道这是预期的行为还是错误。有人可以对此发表评论吗?

修改

新行插入如下:

soci::session sql(Connetion::pool);
sql << "INSERT INTO " << NAME << " (REP_TIMESTAMP, REP_EVENT, REP_LTU_ID, REP_SEC_ID) VALUES (:timestamp, :event, :ltuId, :secId)",
        use (bo.timestamp),
        use (bo.event),
        use (bo.ltuId),
        use (bo.secId);

其中bo.timestampboost::posix_time::ptime,其中包含以下映射:

template<> struct type_conversion<boost::posix_time::ptime> {
    typedef long long base_type;
    static void from_base(const long long& t, indicator& i, boost::posix_time::ptime& target) {
        target = Helper::Time::timeFrom(t);
    }
    static void to_base(const boost::posix_time::ptime& d, long long& target, indicator& i) {
        target = Helper::Time::secondsSinceEpoch(d);
        i = i_ok;
    }
};

Helper::Timeptime转换为自1970年1月1日以来的秒数。我没有看到如何使用此代码将字符串添加到列REP_TIMESTAMP中。

1 个答案:

答案 0 :(得分:1)

SQLite使用dynamic typing;您为列声明的类型几乎没有效果。

您从数据库中获取字符串值,因为您的程序将字符串值写入数据库。 如果要强制实施列类型,则必须添加单独的检查约束:

CREATE TABLE MyTable(
    MyColumn INTEGER NOT NULL CHECK(typeof(MyColumn) = 'integer'),
    ...
)