绑定或列索引超出范围SQLITE C ++

时间:2019-03-21 14:18:20

标签: c++ sqlite bind

我遇到错误:绑定索引或列索引超出范围。该程序的目的是将数据从 .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;
}

1 个答案:

答案 0 :(得分:0)

您的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
)

这未经测试,但我认为应该可以。

相关问题