【问题标题】:Bad cast while getting data from PostgreSQL database using SOCI使用 SOCI 从 PostgreSQL 数据库获取数据时出现错误转换
【发布时间】:2012-07-21 18:45:43
【问题描述】:

我在 PostgreSQL 中有一个数据库。而且我有 sql 查询(顺便说一句,在 PostgreSQL 中效果很好,所以 sql 代码没有错):

SELECT COUNT(*) as size, creation_date FROM item INNER JOIN raf_item USING (id) INNER JOIN item_detail USING (id) GROUP BY creation_date;

其中创建日期在 PostgreSQL 中定义为 creation_date Date;。查询返回,例如(取决于我的数据库中的内容):

size | creation_date
21   | 12-31-2012
18   | 04-03-2002

我正在使用 SOCI + C++ 从这个查询中获取数据。我的整个 C++ 代码:

#include <iostream>
#include <cstdlib>
#include <soci.h>
#include <string>
#include <postgresql/soci-postgresql.h>
using namespace std;

bool connectToDatabase(soci::session &sql, string databaseName, string user, string password)
{
    try
    {
        sql.open(soci::postgresql, "dbname=" +databaseName + " user="+user + " password="+password);
    }
    catch (soci::postgresql_soci_error const & e)
    {
        cerr << "PostgreSQL error: " << e.sqlstate() << " " << e.what() << std::endl;
        return false;
    }
    catch (std::exception const & e)
    {
        cerr << "Some other error: " << e.what() << std::endl;
        return false;
    }
    return true;
}

void getDataFromDatabase(soci::session &sql)
{
    soci::row r;
    sql << "select count(*) as size, creation_date from item inner join raf_item using (id) inner join item_detail using (id) group by creation_date;", soci::into(r);
    for(std::size_t i = 0; i != r.size(); ++i)
    {
        cout << r.get<int>(i);
        tm when = r.get<tm>(i);
        cout << asctime(&when);
    }
}

int main(int argc, char **argv)
{
    soci::session sql;
    bool success = connectToDatabase(sql, "testdb", "testuser", "pass");
    if (success)
    {
        cout << "Connected.\n";
        getDataFromDatabase(sql);
    }

    else
        cout << "Not connected.\n";
    return 0;
}

但是当我尝试运行应用程序时出现此错误(编译正常):

在抛出 'std::bad_cast' 实例后调用终止
what(): std::bad_cast 中断(核心转储)

请帮忙,编译好的时候我真的不知道如何解决这个问题。

也许问题是 creation_date 是 DATE 并且 tm 也保持时间...?如果是这样,如何解决这个问题?

【问题讨论】:

  • 您是否尝试过在调试器中运行您的可执行文件?
  • @cdhowie:不,我没有 - 不幸的是,我对调试了解不多:/
  • 这可能是一个很好的学习方式。
  • @cdhowie:我知道你是对的,我只是想也许有人对 soci 有这个问题并且可以提供帮助......我几乎可以肯定问题出在 creation_date 类型......
  • 那么,您尝试过什么来确认这一点?您是否尝试向cout 写信以验证崩溃发生的确切位置?看起来您收到了这次崩溃,然后就放弃了。至少要弄清楚是哪条线路触发了崩溃。

标签: c++ postgresql postgresql-9.1 soci


【解决方案1】:

虽然您确实解决了问题,但您发布的代码更像是一种解决方法,而不是问题的真正解决方案。

您的问题是, COUNT(*) 返回 bigint(或 int8)类型的值,如 here 所述, soci 将 bigint 转换为 long long int 类型,如 in this chart 所述。如果类型不完全匹配,则会抛出 bad_cast 异常。

因此,您问题中的代码应为cout &lt;&lt; r.get&lt;long long&gt;(i); 以避免bad_cast 异常。

【讨论】:

    【解决方案2】:

    好的,我自己解决了!:)

    这是实际上可以正常工作的代码(我只用下面的代码替换了getDataFromDatabase):

    void getDataFromDatabase(soci::session &sql)
    {
        long size;
        string date;
    
        soci::row r;
        sql << "select count(*) as size, creation from item inner join raf_item using (id) inner join item_detail using (id) group by creation;", soci::into(r);
        for(std::size_t i = 0; i != r.size(); ++i)
        {
            const soci::column_properties & props = r.get_properties(i);
    
        cout << '<' << props.get_name() << '>';
    
        switch(props.get_data_type())
        {
        case soci::dt_string:
            cout << r.get<std::string>(i);
            break;
        case soci::dt_double:
            cout << r.get<double>(i);
            break;
        case soci::dt_integer:
            cout << r.get<int>(i);
            break;
        case soci::dt_unsigned_long:
            cout << r.get<unsigned long>(i);
            break;
        case soci::dt_long_long:
            cout << r.get<long long>(i);
            size = r.get<long long>(i);
            break;
        case soci::dt_date:
            std::tm when = r.get<std::tm>(i);
            cout << asctime(&when);
            date = asctime(&when);
            break;
        }
    
        cout << "\n" << size << "\n";
        cout << "\n" << date << "\n";
    }
    

    【讨论】:

      猜你喜欢
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 2019-11-12
      • 1970-01-01
      相关资源
      最近更新 更多