1

在 C++ 中,我正在使用mysql.h库,但无法捕获 MySQL 错误(例如,由于主键冲突而导致插入失败)。

我试过了

#include <mysql.h>
// ...
try{
    res = mysql_perform_query(conn, sqlIn);
} catch (...) {
// ...
}

但它仍然不能避免中止:

MySQL query error : Duplicate entry

我正在使用 PuTTy 接口运行已编译的 c++ 程序,当程序中止时,它会重现 MySQL 的错误(无论我是否使用 TRY CATCH)。
我没有找到任何对 MySQL 使用 catch 语句的特定异常代码的引用。

显然,即使使用“一揽子”语法(),C++(使用这个库mysql.h)也不会捕获 MySQL 回调错误catch (...)。由于这种语法应该捕获所有异常,但在这种情况下没有,我不知道这里发生了什么。如何捕获 SQL 异常?

4

4 回答 4

5

mysql C 库不会抛出任何异常;它只是像大多数其他 C 库一样,在一个公共位置(如 errno)设置错误信息并返回一个状态。由您的客户端代码检查返回并引发错误/异常。

如果您需要轻松解决问题,请尝试使用 mysql++ (AKA mysqlpp)。这是一款我可以担保的软件;坚如磐石! http://tangentsoft.net/mysql++/

于 2012-10-09T23:50:53.410 回答
2

尝试在 mysql C 库周围使用一些 c++ 包装器。例如http://mysqlcppapi.sourceforge.net/

C 不会抛出你必须通过 mysql_errorno 函数检查的异常。

于 2012-10-09T03:52:19.203 回答
1

我不会推荐 Mysql C++ 库有两个原因 1. 很难得到支持。2.相比Mysql C库慢

您可以使用 mysql_error() 和 mysql_errno() API 来了解错误并手动通过异常

于 2012-10-10T07:28:39.057 回答
1

根据 kingstonian 的建议,我在 mysql 周围使用了 mysql++ 包装器(要在 ubuntu 中安装,请参阅我的回答另一个 SO 问题的食谱

下面的代码用于测试错误处理,其中在键中插入了重复值 (Id_Target = 9)。使用适合您的数据库结构的插入来适应您自己的需求。

#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include </usr/include/mysql++/mysql++.h>


// sudo g++ -o /temp/zdelMySQLpp01c $(mysql_config --cflags) /home/ubuntu/zdelMySQLpp01c.cpp $(mysql_config --cflags --libs) -l pthread -std=c++0x -g -L/usr/lib/mysql -lmysqlclient -lmysqlpp

using namespace mysqlpp;
using namespace std;

//MySQL type
struct connection_details {
        char *server;
        char *user;
        char *password;
        char *database;
};

int main(int argv, char** argc){

// MySQL connection (global)
struct connection_details mysqlD;
mysqlD.server = (char *)"localhost";  // where the mysql database is
mysqlD.user = (char *)"root";       // the root user of mysql   
mysqlD.password = (char *)"XXXXXX"; // the password of the root user in mysql
mysqlD.database = (char *)"test";   // the databse to pick

// connect to the mysql database
mysqlpp::Connection conn(false);
if (conn.connect(mysqlD.database, mysqlD.server, mysqlD.user, mysqlD.password)) {
    //printf("ALOALO funcionou conexao\n");
    mysqlpp::Query query = conn.query("INSERT INTO test.target (Id_Target, Ds_Target, Ds_Target_Name, Ds_Target_PWD, Ds_Target_Email, Ds_Target_Icon) VALUES ('9', 'test', 'name', 'pass', 'email', NULL)");
        if (mysqlpp::StoreQueryResult res = query.store()) {
                cout << "We have:" << endl;
                for (size_t i = 0; i < res.num_rows(); ++i) {
                    cout << '\t' << res[i][0] << endl;
                }
        } else {
                cerr << "Failed to get item list: " << query.error() << endl;
                return 1;
    }
        return 0;
}
}
于 2012-10-11T16:44:10.963 回答