2009-03-05 6 views
1

Je suis en train de construire une chaîne dans Cocoa pour l'utiliser comme une instruction SQL qui sera passée dans les wrappers FMDB pour sqlite; Cependant, la base de données craps avec un échec BAD_ACCESS. J'ai le code suivant:Utilisation de guillemets simples lors de la construction d'une chaîne dans Cocoa

préfixe = @ "SELECT * FROM Table WHERE Champ1 LIKE '%";

middle = @ "% 'OU Field2 LIKE'%";

suffixe = @ "% 'ORDERY BY";

orderby = «% 'ORDER BY Fieldnames»; SqlStatement = [NSString stringWithFormat: @ "% @% @% @% @% @% @", préfixe, searchString, milieu, searchString, suffixe, orderby];

Lors de l'exécution instructionSQL finit contenant quelque chose comme ce qui suit:

SELECT * FROM table où Champ1 comme \ '% A% \' OR Champ2 comme \ '% A% \' ORDER BY Noms des champs

Pour une raison quelconque, un \ est ajouté dans la chaîne qui provoque la bombe de la base de données.

Des idées comment je peux garder le \ d'apparaître dans ma chaîne?

MISE À JOUR: Quand je sortie ma variable via NSLog j'obtiens ce qui suit: SELECT * FROM table où Champ1 LIKE 'OX1.87A8013DBD18F-1027' OU Champ2 LIKE « OX1.87A8013DBD18F-1027'ORDER PAR Fieldname.

Le problème semble être lié à l'utilisation de% A dans la chaîne. Même si je code dur la variable sqlStatement pour inclure '% A%' le% A semble être converti en une adresse mémoire ou quelque chose. Si je fais '% ABAP%', j'obtiens la sortie comme 'OX1.87A8013DBD18F-1027BAP'. Notez que je perds le signe%.

+0

Quelle base de données ciblez-vous? – jonnii

+0

S'il vous plaît modifier le message original au code de format correctement. –

+0

Vous avez besoin d'utiliser des paramètres. Voir mon message. – jonnii

Répondre

0

La chaîne semble être construite correctement. Si je lance le code:

int main(int argc, char *argv[]) 
{ 
    NSAutoreleasePool* pool = [NSAutoreleasePool new]; 

    NSString* prefix = @"SELECT * FROM Table WHERE Field1 LIKE '%"; 

    NSString* middle = @"%' OR Field2 LIKE '%"; 

    NSString* suffix = @"%' ORDERY BY "; 

    NSString* orderby = @"%' ORDER BY Fieldnames"; 

    NSString* sqlStatement = [NSString stringWithFormat:@"%@%@%@%@%@%@", prefix, @"blah", middle, @"blah", suffix, orderby]; 

    NSLog(@"sqlStatement: %@", sqlStatement); 

    [pool drain]; 

    return 0; 
} 

Je reçois le résultat suivant dans la console:

2009-03-05 08:04:29.734 Untitled[79999:813] sqlStatement: SELECT * FROM Table WHERE Field1 LIKE '%blah%' OR Field2 LIKE '%blah%' ORDERY BY %' ORDER BY Fieldnames 
+0

Lorsque je génère ma variable via NSLog, je reçois ce qui suit: SELECT * FROM Tableau WHERE Champ1 LIKE 'OX1.87A8013DBD18F-1027' OU Champ2 LIKE 'OX1.87A8013DBD18F-1027'ORDER PAR Nom de champ. Le problème est searchString. Mais quand je publie ce champ via NSLog, il semble bon. n'apparaît que dans le débogueur. – radesix

+0

Essayez votre code avec un A au lieu de bla et voir ce qui se passe. – radesix

4

Je vais deviner que vous utilisez SQLite, dans ce cas, vous voulez faire légèrement différemment. Commencez par créer votre requête de la manière suivante:

SELECT * FROM Table WHERE Field1 LIKE ?001 OR Field2 LIKE ?002 ORDER BY Fieldnames 

La syntaxe? 000 est pour les paramètres. Espérons que cela vous devez mentionner

sqlite3_bind_text(statement, 1, [@"%bar%" UTF8String], -1, SQLITE_STATIC); 
sqlite3_bind_text(statement, 2, [@"%foo%" UTF8String], -1, SQLITE_STATIC); 

dans la bonne direction:

Vous pouvez ensuite utiliser sqlite3_bind_text pour lier vos paramètres.

0

Que voulez-vous dire par "at runtime"? Voulez-vous dire dans le débogueur Xcode?

Semble que vous ciblez this problem.

Les guillemets simples échappé backslash- ne semblent apparaître à l'intérieur de la variable de la fenêtre du débogueur Xcode colonne sommaire . Examiner la valeur de "sql" manuellement gdb révèle le format correct:

(gdb) po sql select * from t_state où state_code = 'XX'

et NSLogging la chaîne laisse aussi la antislashs. Donc, je dirais que ces guillemets simples sont échappés pour certains raison seulement dans le processus de Xcode formatant l'objet pour afficher dans la vue variable .

+0

Alors pourquoi le bombardement sqlite avec BAD_ACCESS? – radesix

2

En ce qui concerne votre 'mise à jour':

Il semble que le "% A" s'utilisé comme spécificateur de format, à savoir:

% A: une virgule flottante 64 bits nombre (double), imprimé en notation scientifique avec un 0x et un chiffre hexadécimal avant la virgule décimale au moyen d'un P majuscule pour introduire l'exposant

Voir String Programming Guide for Cocoa.

Donc, vous utilisez la chaîne sqlStatement plus tard comme une chaîne de contrôle de format, ce qui est mauvais. Si vous avez besoin de passer sqlStatement à une méthode/fonction qui interprète la chaîne comme un spécificateur de format, vous devez le passer comme do_query(@"%@", sqlStatement)

Questions connexes