【问题标题】:Bind or column index out of range SQLITE C++绑定或列索引超出范围 SQLITE C++
【发布时间】:2019-10-31 11:05:15
【问题描述】:

我遇到错误:绑定或列索引超出范围。该程序的目的是将数据从 .mlex 文件导入数据库。该程序的输出是我想要的,但是对于我要导入的每一行都会出现错误。 如果您对改进我的程序有任何建议? 我对每个绑定都有相同的错误,我不确定查询的语法。

sqlite3 *db; //Declare pointer pour la db

int check(int rc);

int main(int argc, char *argv[])
{
    setlocale(LC_ALL, ""); //pour les accents 

    char *zErrMsg = 0;
    //ouvre la db;
    int rc = sqlite3_open("base.db", &db);
    if (rc)
    {
        std::cerr << "Impossible d'ouvrir la db" << sqlite3_errmsg(db);
        sqlite3_close(db);
        return 0;
    }
    //création d'un tableau
    const char *zSql = "CREATE TABLE IF NOT EXISTS FLLL(ID INTEGER PRIMARY KEY AUTOINCREMENT,Forme VARCHAR(40), Categorie VARCHAR(40), Lemme VARCHAR(40), Bloc varchar(40))";
    rc = sqlite3_exec(db, zSql, NULL, NULL, &zErrMsg);
    if (rc != SQLITE_OK) {
        std::cerr << "SQL error :" << zErrMsg;
        sqlite3_close(db);
        return 0;
    }

    //ouvre le fichier
    std::ifstream monFlux("C:/Users/Quent/OneDrive/Bureau/Dico/LEFFF/lefff-3.45.mlex", std::ios::in);
    if (monFlux) std::cout << "fichier ouvert"<<std::endl;
    else {
        std::cout << "erreur, ouverture impossible";
        monFlux.close();
        return 0;
    }
    //lire ligne par ligne
    std::string ligne;
    int idx = 0;
    while (std::getline(monFlux, ligne,'\n'))
    {
        int cpt = 0;
        idx++;
        std::istringstream iss(ligne+'\t');
        std::string token;
        std::cout << ligne << std::endl;

        sqlite3_stmt *ppStmt1 = 0;
        sqlite3_stmt *ppStmt2 = 0;
        sqlite3_stmt *ppStmt3 = 0;
        sqlite3_stmt *ppStmt4 = 0;
        const char *pzTail = 0;

        const char *zSql1 = "INSERT INTO FLLL(Forme) VALUES(?)";
        const char *zSql2 = "UPDATE FLLL SET Categorie = ? WHERE ID = (?)";
        const char *zSql3 = "UPDATE FLLL SET Lemme = ? WHERE ID = (?)";
        const char *zSql4 = "UPDATE FLLL SET BLOC = ? WHERE ID = (?)";

        if (sqlite3_prepare_v2(db, zSql1, strlen(zSql1) + 1, &ppStmt1, &pzTail) != SQLITE_OK || sqlite3_prepare_v2(db, zSql2, strlen(zSql2) + 1, &ppStmt2, &pzTail) != SQLITE_OK || sqlite3_prepare_v2(db, zSql3, strlen(zSql3) + 1, &ppStmt3, &pzTail) != SQLITE_OK || sqlite3_prepare_v2(db, zSql4, strlen(zSql4) + 1, &ppStmt4, &pzTail) != SQLITE_OK)
        {
            std::cerr << "db erreur :" << sqlite3_errmsg(db);
            sqlite3_close(db);
            return 0;
        }
        while (std::getline(iss, token, '\t')) 
        {
            cpt++;
            const char *c = token.c_str();
            switch (cpt)
            {
            case 1: rc = sqlite3_bind_text(ppStmt1,1,c , -1, SQLITE_STATIC);
                if (rc) check(rc);
                rc = sqlite3_bind_int(ppStmt1, 2, idx);
                if (rc) check(rc); //error is here 
                rc = sqlite3_step(ppStmt1);
                if (rc!=SQLITE_DONE) check(rc);
                rc = sqlite3_reset(ppStmt1);
                if (rc) check(rc);
                break;

            case 2: rc = sqlite3_bind_text(ppStmt2, 1, c, -1, SQLITE_STATIC);
                if (rc) check(rc);
                rc = sqlite3_bind_int(ppStmt2,2, idx);
                if (rc) check(rc); //error is here 
                rc = sqlite3_step(ppStmt2);
                if (rc != SQLITE_DONE) check(rc);
                rc = sqlite3_reset(ppStmt2);
                if (rc) check(rc);
                break;

            case 3: rc = sqlite3_bind_text(ppStmt3, 1, c, -1, SQLITE_STATIC);
                if (rc) check(rc);
                rc = sqlite3_bind_int(ppStmt3, 2, idx);
                if (rc) check(rc); //error is here 
                rc = sqlite3_step(ppStmt3);
                if (rc != SQLITE_DONE) check(rc);
                rc = sqlite3_reset(ppStmt3);
                if (rc) check(rc);
                break;

            case 4: rc = sqlite3_bind_text(ppStmt4, 1, c, -1, SQLITE_STATIC);
                if (rc) check(rc);
                rc = sqlite3_bind_int(ppStmt4,2, idx);
                if (rc) check(rc); //error is here 
                rc = sqlite3_step(ppStmt4);
                if (rc != SQLITE_DONE) check(rc);
                rc = sqlite3_reset(ppStmt4);
                if (rc) check(rc);
                break;
            default:
                break;
            }
            //std::cout<<token<<std::endl;

        }
        sqlite3_finalize(ppStmt1);
        sqlite3_finalize(ppStmt2);
        sqlite3_finalize(ppStmt3);
        sqlite3_finalize(ppStmt4);
    }

    std::cout << "jai mangéà";
    getchar();
    sqlite3_close(db);
    monFlux.close();
    return 0;
}

【问题讨论】:

    标签: c++ sqlite bind


    【解决方案1】:

    您的 INSERT 查询仅插入一列 (Forme),但您的表有 5 列。

    可能的解决方案是:

    1. 插入具有NULL 值的其他列
    2. 使用默认值创建表。

    插入NULL

    这意味着更改您的 INSERT 查询以包含其他列。

    INSERT INTO FLLL(Forme, Categorie, Lemme, Bloc) VALUES (?, NULL, NULL, NULL)
    

    注意ID 列被省略了,因为它是由 SQLite 自动递增的。

    使用默认值创建表

    这意味着更改您的 CREATE 语句(并单独保留 INSERT 查询)。

    CREATE TABLE IF NOT EXISTS FLLL
    (
        ID INTEGER PRIMARY KEY AUTOINCREMENT,
        Forme VARCHAR(40)      DEFAULT NULL,
        Categorie VARCHAR(40)  DEFAULT NULL,
        Lemme VARCHAR(40)      DEFAULT NULL,
        Bloc VARCHAR(40)       DEFAULT NULL
    )
    

    这是未经测试的,但我认为它应该可以工作。

    【讨论】:

    • 感谢您的回答,我发现了我的错误:第一次绑定我什么都不绑定。但是如果有什么可以改进我的程序的,请随时说出来。
    猜你喜欢
    • 2017-11-01
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    • 2020-09-26
    相关资源
    最近更新 更多