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é:
sqlite3_prepare_v2()
échoué car votre string de requête était invalide du fait que vos strings contenaient le statement
était NULL
ou contenait une valeur de la poubelle sqlite3_step()
s'est écrasé sqlite3_step()
pointeur invalide a été passé en argument. Voici la solution:
"
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:@"\\\""];
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
.