2013-07-26 18 views
1

我使用SOCI庫訪問的sqlite3的數據庫:SOCI並不總是返還相同種類對於數字列

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還是soci。解決方法似乎很簡單:檢查行值的類型,如果它是一個字符串,則將其轉換爲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::Time變換ptime到數自從1970年1月1日以後又回來了。我沒有看到如何使用此代碼可以將字符串加入列REP_TIMESTAMP

回答

1

SQLite使用dynamic typing;您爲列聲明的類型幾乎不起作用。

您從數據庫中獲取一個字符串值,因爲您的程序將一個字符串值寫入數據庫。 如果你想強制列類型,你必須添加一個單獨的檢查約束:

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

有趣。但是,我在soci調用的頂部有一個ORM層,它是類型安全的,不能將字符串寫入此列。是否有可能我提供的int值被轉換爲soci或sqlite3 API中的字符串?我想我會嘗試添加檢查,看看會發生什麼。 – flyx

+0

可以使用[type affinity](http://www.sqlite.org/datatype3.html#affinity)轉換類型,但是'NUMERIC'列不能以這種方式獲取字符串。您確實需要檢查以查看字符串來自哪裏。 –

+0

我試圖將檢查添加到我的數據庫佈局。現在每個提交都被「約束失敗」拒絕。 SQLite似乎只有一個'integer'類型,所以即使我在C++端插入'long long',它應該是SQLite的整數,對吧?實際上沒有其他地方的東西被提交到數據庫,所以值*有*要轉換爲字符串在soci或sqlite的某處。 – flyx

相關問題