You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++连接MySQL使用Statement无法查询结果及语句效率疑问

C++ MySQL连接:Statement执行INSERT后SELECT无结果及效率对比问题

问题描述

我使用C++的MySQL Connector编写了数据库连接代码,用Statement执行INSERT语句后立刻执行SELECT,却无法获取表内信息,但改用PreparedStatement就能正常运行。想请教两个问题:

  1. 这种INSERT后直接SELECT的流程是否存在问题?
  2. 向数据库添加数据时,PreparedStatement和Statement哪种效率更高?

代码示例

#include <iostream>
#include <Windows.h>

#include "jdbc/mysql_connection.h"
#include "jdbc/cppconn/driver.h"
#include "jdbc/cppconn/exception.h"
#include "jdbc/cppconn/resultset.h"
#include "jdbc/cppconn/statement.h"
#include "jdbc/cppconn/prepared_statement.h"

#ifdef _DEBUG
#pragma comment(lib, "debug/mysqlcppconn.lib")
#else
#pragma comment(lib, "mysqlcppconn.lib")
#endif

using namespace std;

std::string Utf8ToMultiByte(std::string utf8_str);

int main()
{
    try
    {
        sql::Driver* driver; 
        sql::Connection* connection; 
        sql::Statement* statement; 
        sql::ResultSet* resultset; 

        driver = get_driver_instance();

        connection = driver->connect("tcp://127.0.0.1:3306", "root", "");

        if (connection == nullptr)
        {
            cout << "connect failed" << endl;
            exit(-1);
        }

        connection->setSchema("logindata");

        statement = connection->createStatement();
        resultset = statement->executeQuery("insert into new_table(number, id, wincount, totalgameplay) values(4, 132, 232349, 123)");
        resultset = statement->executeQuery("select * from new_table ");

        for (;resultset->next();)
        {
            cout << resultset->getInt("id") << " : " <<
                Utf8ToMultiByte(resultset->getString("wincount")) << " : " <<
                Utf8ToMultiByte(resultset->getString("totalgameplay")) << endl;
        }

        delete resultset;
        delete statement;
        delete connection;
    }
    catch (sql::SQLException e)
    {
        cout << "# ERR: SQLException in " << __FILE__;
        cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
        cout << "# ERR: " << e.what();
        cout << " (MySQL error code: " << e.getErrorCode();
        cout << ", SQLState: " << e.getSQLState() << " )" << endl;
    }
    return 0;
}

std::string Utf8ToMultiByte(std::string utf8_str)
{
    std::string resultString; char* pszIn = new char[utf8_str.length() + 1];
    strncpy_s(pszIn, utf8_str.length() + 1, utf8_str.c_str(), utf8_str.length());
    int nLenOfUni = 0, nLenOfANSI = 0; wchar_t* uni_wchar = NULL;
    char* pszOut = NULL;
    // 1. utf8 Length
    if ((nLenOfUni = MultiByteToWideChar(CP_UTF8, 0, pszIn, (int)strlen(pszIn), NULL, 0)) <= 0)
        return nullptr;
    uni_wchar = new wchar_t[nLenOfUni + 1];
    memset(uni_wchar, 0x00, sizeof(wchar_t)*(nLenOfUni + 1));
    // 2. utf8 --> unicode
    nLenOfUni = MultiByteToWideChar(CP_UTF8, 0, pszIn, (int)strlen(pszIn), uni_wchar, nLenOfUni);
    // 3. ANSI(multibyte) Length
    if ((nLenOfANSI = WideCharToMultiByte(CP_ACP, 0, uni_wchar, nLenOfUni, NULL, 0, NULL, NULL)) <= 0)
    {
        delete[] uni_wchar; return 0; 
    }
    pszOut = new char[nLenOfANSI + 1];
    memset(pszOut, 0x00, sizeof(char)*(nLenOfANSI + 1));
    // 4. unicode --> ANSI(multibyte)
    nLenOfANSI = WideCharToMultiByte(CP_ACP, 0, uni_wchar, nLenOfUni, pszOut, nLenOfANSI, NULL, NULL);
    pszOut[nLenOfANSI] = 0;
    resultString = pszOut;
    delete[] uni_wchar;
    delete[] pszOut;
    return resultString;
}

问题解答

1. INSERT后SELECT无结果的原因

你用statement->executeQuery()执行INSERT语句是错误用法。executeQuery()专门用于执行查询类SQL(如SELECT),它会返回查询结果集;而INSERT、UPDATE、DELETE这类数据操作语句,必须用executeUpdate()方法,该方法返回受影响的行数,不会生成结果集。

你的代码中用executeQuery()执行INSERT,会导致Statement内部状态异常,后续的SELECT查询也会被干扰,因此无法获取到结果。而改用PreparedStatement时,你应该是用了正确的executeUpdate()来执行INSERT,所以整个流程能正常运行。

修正方法:将INSERT语句的执行代码替换为:

// 执行INSERT并获取受影响行数
int affectedRows = statement->executeUpdate("insert into new_table(number, id, wincount, totalgameplay) values(4, 132, 232349, 123)");
cout << "成功插入 " << affectedRows << " 条数据" << endl;

2. PreparedStatement与Statement的效率对比

  • 重复执行相同结构的SQL时,PreparedStatement效率更高:
    PreparedStatement会在数据库端预编译SQL模板,后续执行仅需传入参数,避免了重复解析、优化SQL的开销。而Statement每次执行都会重新编译SQL,重复执行时性能差距明显。
  • 单次执行简单SQL时,两者效率差异可忽略:
    对于只执行一次的简单语句,编译开销占比极低,两者性能差不多。

此外,PreparedStatement还有额外优势:

  • 自动处理参数转义,彻底避免SQL注入风险;
  • 参数化写法比字符串拼接更清晰,代码可读性和维护性更好。

因此,日常开发中优先推荐使用PreparedStatement,尤其是涉及参数传递或需要重复执行的场景。


内容的提问来源于stack exchange,提问作者NW K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 15:55:20