Pourquoi dois-je obtenir un SQLITE_MISUSE : de l'erreur de Mémoire?

Je suis en train d'écrire un iOS application qui accède directement SQLite. J'ai fait ce genre de chose de nombreuses fois sur Android, donc j'ai du mal à voir où est mon erreur se situe - toutefois, mes plaquettes sont de retour le SQLITE_MISUSE d'erreur (code 21), avec le message "out of Memory". Ci-dessous sont les étapes que j'ai prises à me conduire à cette insertion.

Tout d'abord, le la création de la table:

NSString *sql = @"CREATE TABLE IF NOT EXISTS UsersTable (lastName TEXT,id TEXT PRIMARY KEY NOT NULL,picture BLOB,firstName TEXT,age TEXT,email TEXT,sex TEXT,height TEXT,weight TEXT)";

//create the database if it does not yet exist
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: path ] == NO)
{
    const char *dbpath = [path UTF8String];

    //This was if (sqlite3_open(dbpath, &store) == SQLITE_OK) , but it has not made a difference.
    if (sqlite3_open_v2(dbpath, &store, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) == SQLITE_OK)
    {
        char *errMsg = NULL;
        const char *sql_stmt = [sql UTF8String];

        if (sqlite3_exec(store, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
        {
            NSLog(@"Failed to create table: %s", errMsg);
        }
        if (errMsg)
            sqlite3_free(errMsg);
    }
    else
    {
        NSLog(@"Failed to open/create database");
    }
}

Prochain, le insérer (en utilisant l'adresse e-mail de l'ID utilisateur):

INSERT INTO UsersTable (id,lastName,firstName,email) VALUES ("[email protected]","Smith","John","[email protected]")

Je suis en utilisant un sélecteur pour l'ensemble de la base de données des interactions, de sorte que le texte ci-dessus est passé ici:

-(int)execSQL:(NSString *)statement
{
    NSLog(@"%@",statement);

    const char *insert_stmt = [statement UTF8String];
    sqlite3_stmt *stmnt;

    sqlite3_prepare_v2(store, insert_stmt, -1, &stmnt, NULL);
    int result = sqlite3_step(stmnt);

    sqlite3_finalize(stmnt);

    if (result != SQLITE_OK)
    {
        NSLog(@"Error: %s", sqlite3_errmsg(store));//This prints "Error: out of memory"
    }
    return result;
}

Ce que je fais mal?

  • Obtenez le message d'erreur. NSLog(@"Error: %s", sqlite3_errmsg(store));.
  • sqlite s'attend à des valeurs de texte pour être entre guillemets simples, pas de guillemets doubles.
  • Une dernière chose - juste au cas où - ne pas utiliser un format de chaîne pour créer vos instructions SQL. La préparation de la déclaration d'utiliser ensuite sqlite3_bind_xxx de lier la valeur dans la requête. INSERT INTO table (c1, c2, c2) VALUES (?, ?, ?). Les appels à sqlite3_bind_xxx remplacera le ? avec la bonne valeur. Cela garantit les valeurs sont correctement cité et caractères spéciaux sont échappées.
  • La "mémoire" d'erreur signifie presque toujours que votre base de données (pointeur de votre sqlite3 * variable) n'a pas été mis correctement avec un appel à sqlite3_open_v2.
  • J'ai ajouté le code que j'utilise pour ouvrir la base de données, et modifier, à l'aide de sqlite3_open à sqlite3_open_v2, mais reçois toujours le même message d'erreur. Toute autre pointeurs? (Je suis actuellement en train de travailler sur vos autres suggestions)
  • Avez-vous vérifié que la base de données est ouvert correctement et par le temps que vous appelez le code pour l'insérer, votre store variable est toujours correctement le programme d'installation à partir de la base de données ouverte? En outre, initialiser store à NULL juste avant l'appel à sqlite3_open et de nouveau après l'appel de sqlite3_close.
  • J'ai mis store à NULL avant mon ouverture, mais ça n'aide pas. Je n'ai pas l'appeler sqlite3_close jusqu'à ce que mon objet est libéré par le garbage collector. N'est-ce que ce doit être appelée après chaque instruction sql?
  • Voir Rob réponse. Vous n'êtes pas l'ouverture de la base de données si le fichier existe déjà. Vous devriez appeler sqlite3_open_v2 si elle existe ou pas. Vous souhaitez simplement créer les tables si ça n'existait pas encore.

InformationsquelleAutor Phil | 2013-03-07