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

使用C++连接SQL Server创建新表时出现报错如何解决

SQL Server 建表失败问题

以下是用于创建SQL Server连接并尝试新建数据表的函数:
我已尝试所有能想到的解决方法,目前毫无头绪。与服务器的连接可正常建立,但始终提示“could not create a new table”。我已查阅Stack Overflow上该主题的相关帖子,仍未找到解决方案。
程序返回的报错如下:
报错截图
以下是主函数及运行截图,可证明简单查询语句可正常运行:
主函数运行截图
原有代码:

void DB::runQuery(string SQLQuery)
{
    SQLCHAR retConString[1024]; // Conection string
    switch (SQLDriverConnect(SQLConnectionHandle, NULL, (SQLCHAR*)"DRIVER={SQL Server}; SERVER=localhost, 1433; DATABASE=myDB; UID=myID; PWD=1234;", SQL_NTS, retConString, 1024, NULL, SQL_DRIVER_NOPROMPT)) {
        // Establishes connections to a driver and a data source
    case SQL_SUCCESS:
        break;
    case SQL_SUCCESS_WITH_INFO:
        break;
    case SQL_NO_DATA_FOUND:
        showSQLError(SQL_HANDLE_DBC, SQLConnectionHandle);
        retCode = -1;
        break;
    case SQL_INVALID_HANDLE:
        showSQLError(SQL_HANDLE_DBC, SQLConnectionHandle);
        retCode = -1;
        break;
    case SQL_ERROR:
        showSQLError(SQL_HANDLE_DBC, SQLConnectionHandle);
        retCode = -1;
        break;
    default:
        break;
    }
    if (retCode == -1)
        print("An error occurred");
    if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, SQLConnectionHandle, &SQLStatementHandle))
        // Allocates the statement
        print("could not allocate the statement");
    if (SQL_SUCCESS != SQLExecDirect(SQLStatementHandle, (SQLCHAR*)SQLQuery.c_str(), SQL_NTS)) {
        // Executes a preparable statement
        showSQLError(SQL_HANDLE_STMT, SQLStatementHandle);
        print("could not execute the statement");
    }
    else {
        char name[256];
        int age;
        while (SQLFetch(SQLStatementHandle) == SQL_SUCCESS) {
            // Fetches the next rowset of data from the result
            SQLGetData(SQLStatementHandle, 1, SQL_C_DEFAULT, &name, sizeof(name), NULL);
            SQLGetData(SQLStatementHandle, 2, SQL_C_DEFAULT, &age, sizeof(age), NULL);
            // Retrieves data for a single column in the result set
            cout << name << " " << age << endl;
        }
    }
}

修复方案

你的代码核心问题是逻辑适配不全,仅适配了有结果集返回的查询类SQL,没有适配CREATE TABLE这类无结果集的DDL语句,导致执行建表语句时触发后续的结果集读取错误,被误判为执行失败。

具体问题及修改点

  • 移除每次执行语句时的重复建连逻辑,把数据库连接初始化抽离到单独的初始化函数,仅在程序启动时执行一次即可,避免连接资源泄漏。
  • 新增参数标记当前执行的SQL是否需要返回结果集,只有SELECT类查询才走结果集读取逻辑,建表、插入、更新这类语句直接跳过即可。
  • 每次执行完语句后释放Statement句柄,避免资源耗尽导致后续执行失败。
  • 额外排查两个非代码问题:确认连接使用的myID账号有myDB数据库的CREATE TABLE权限;确认你执行的建表SQL本身没有语法错误,不存在表名重复、字段类型不合法等问题。

修改后代码

// 连接初始化仅执行一次即可,不要放在runQuery里重复调用
void DB::initConnection() {
    SQLCHAR retConString[1024];
    switch (SQLDriverConnect(SQLConnectionHandle, NULL, (SQLCHAR*)"DRIVER={SQL Server}; SERVER=localhost, 1433; DATABASE=myDB; UID=myID; PWD=1234;", SQL_NTS, retConString, 1024, NULL, SQL_DRIVER_NOPROMPT)) {
    case SQL_SUCCESS:
    case SQL_SUCCESS_WITH_INFO:
        retCode = 0;
        break;
    case SQL_NO_DATA_FOUND:
    case SQL_INVALID_HANDLE:
    case SQL_ERROR:
        showSQLError(SQL_HANDLE_DBC, SQLConnectionHandle);
        retCode = -1;
        break;
    default:
        retCode = -1;
        break;
    }
    if (retCode == -1)
        print("An error occurred in connection");
}

void DB::runQuery(string SQLQuery, bool hasResultSet)
{
    if (retCode == -1) {
        print("Connection is invalid");
        return;
    }

    SQLHSTMT stmt;
    if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, SQLConnectionHandle, &stmt)) {
        print("could not allocate the statement");
        return;
    }

    if (SQL_SUCCESS != SQLExecDirect(stmt, (SQLCHAR*)SQLQuery.c_str(), SQL_NTS)) {
        showSQLError(SQL_HANDLE_STMT, stmt);
        print("could not execute the statement");
        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
        return;
    }

    if (hasResultSet) {
        char name[256];
        int age;
        while (SQLFetch(stmt) == SQL_SUCCESS) {
            SQLGetData(stmt, 1, SQL_C_DEFAULT, &name, sizeof(name), NULL);
            SQLGetData(stmt, 2, SQL_C_DEFAULT, &age, sizeof(age), NULL);
            cout << name << " " << age << endl;
        }
    }

    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
}

调用时执行建表语句传入hasResultSet = false,执行SELECT语句传入hasResultSet = true即可。

内容的提问来源于stack exchange,提问作者רועי סלע

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 23:36:05