Индекс привязки или столбца вне диапазона SQLITE C ++ - PullRequest
0 голосов
/ 21 марта 2019

У меня ошибка: Привязка или индекс столбца вне диапазона .Цель программы - импортировать данные из файла .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 голосов
/ 21 марта 2019

Ваш запрос 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
)

Это не проверено, но я думаю, что оно должно работать.

...