Utilisation de NSSsortingng / parameters dans l'instruction SQLite iOS

J'ai mon code ci-dessous. Mes valeurs _emailVaue _passwordValue et _nameValue sont extraites de UITextFields dans mon application. J'avais l'printing que le passage de ces valeurs dans les parameters de mon code SQLite me permettrait d'avoir des caractères spéciaux dans ces valeurs, comme des guillemets doubles ("), mais si je les place, le SQLite se bloque. suis-je mal?

Je suis conscient qu'il est probablement préférable d'utiliser quelque chose comme FMDB, mais j'espérais qu'il y aurait une solution plus rapide pour me faire passer à travers une démo à venir.

J'apprécierais toute aide, merci!

 if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK) { NSSsortingng *insertSQL = [NSSsortingng ssortingngWithFormat: @"INSERT INTO CONTACTS (email, password, name) VALUES (\"%@\", \"%@\", \"%@\")", _emailValue, _passwordValue, _nameValue]; NSLog(insertSQL); const char *insert_stmt = [insertSQL UTF8Ssortingng]; sqlite3_prepare_v2(_contactDB, insert_stmt, -1, &statement, NULL); if (sqlite3_step(statement) == SQLITE_DONE) { } else { } sqlite3_finalize(statement); sqlite3_close(_contactDB); } 

J'espère que vous pouvez répondre à ma propre question si cela semble fonctionner. J'espère que quelqu'un le finda utile. J'apprécierais toute rétroaction sur où je pourrais aller mal.

 sqlite3_stmt *statement; const char *dbpath = [_databasePath UTF8Ssortingng]; const char *insertSQL; if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK) { insertSQL = "INSERT INTO CONTACTS (email, password, name) VALUES (?, ?, ?)"; if(sqlite3_prepare_v2(_contactDB, insertSQL, -1, &statement, NULL) == SQLITE_OK) { sqlite3_bind_text(statement, 1, [_emailValue UTF8Ssortingng], -1, SQLITE_TRANSIENT); sqlite3_bind_text(statement, 2, [_passwordValue UTF8Ssortingng], -1, SQLITE_TRANSIENT); sqlite3_bind_text(statement, 3, [_nameValue UTF8Ssortingng], -1, SQLITE_TRANSIENT); } if (sqlite3_step(statement) == SQLITE_DONE) { //worked } else { //didn't work } sqlite3_finalize(statement); sqlite3_close(_contactDB); } 

Je vais essayer d'expliquer ce qui s'est passé avec votre code et comment il pourrait être amélioré afin que le crash ne se produise pas. Je suis tout à fait d'accord avec l'utilisation des arguments liés, cette réponse est affichée uniquement car elle représente une réponse à la façon dont votre erreur peut être corrigée, et pourrait aider les personnes qui n'ont pas le time de passer aux instructions liées.

Voici ce qui est arrivé:

  1. sqlite3_prepare_v2() échoué car votre string de requête était invalide du fait que vos strings contenaient le
  2. en raison de ce qui précède, statement était NULL ou contenait une valeur de la poubelle
  3. sqlite3_step() s'est écrasé sqlite3_step() pointeur invalide a été passé en argument.

Voici la solution:

  1. échapper toutes vos strings, en remplaçant " par \" , cela va générer une requête valide; si vous utilisiez ' dans votre requête, alors vous devrez replace ' 's par \'

Exemple d'email:

 NSSsortingng *escapedEmail = [_emailValue ssortingngByReplacingOccurrencesOfSsortingng:@"\"" withSsortingng:@"\\\""]; 
  1. Même si vous êtes sûr que la requête est correcte, il est toujours obligatoire de vérifier le résultat de sqlite3_prepare_v2() avant d'utiliser l'instruction dans d'autres appels sqlite .

En règle générale, vous devez coder de façon très défensive lorsque vous manipulez des API C car C ne vous pardonne pas si vous oubliez de searchr des pointeurs NULL . Objective-C est plus souple, car il vous permet d'envoyer des messages à des objects nil .