4

アプリの検索を作成しているときに、FMDB SQLite Wrapper(https://github.com/ccgus/fmdb)を使用しているときに問題が発生しました。

このSQLコマンドを使用してデータベースを検索すると、すべて問題ありません。13個のオブジェクトが返され、使用できます。

FMResultSet *rs = [db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE '%Daimler%'"];

しかし、次のようにユーザー入力からsearchQueryを挿入しようとすると:

FMResultSet *rs = [db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE (?)", theSearchQuery];

...値はSQLコマンドに挿入されません。そして、DBから返されたオブジェクトを取得しません。文字列(theSearchQuery)が最初の例で記述されたものと同じであっても。

さらに、便宜上、FMDBのドキュメントの一部を投稿します。:)

Data Sanitization

FMDBにSQLステートメントを提供するときは、挿入する前に値を「サニタイズ」しようとしないでください。代わりに、標準のSQLiteバインディング構文を使用する必要があります。

myTableの値に挿入(?、?、?)?文字は、挿入される値のプレースホルダーとしてSQLiteによって認識されます。実行メソッドはすべて、適切にエスケープされた可変数の引数(またはNSArrayやva_listなどのそれらの引数の表現)を受け入れます。

したがって、これ(またはこのようなもの)を行うべきではありません:

[db executeUpdate:[NSString stringWithFormat:@ "INSERT INTO myTable VALUES(%@)"、@ "this has \" lots of' bizarre \ "quotes'"]]; 代わりに、次のことを行う必要があります。

[db executeUpdate:@ "INSERT INTO myTable VALUES(?)"、@ "this has \" lots of'bizarre \ "quotes'"]; -executeUpdate:メソッド(またはva_listをパラメーターとして受け入れるバリアント)に提供されるすべての引数は、オブジェクトである必要があります。以下は機能しません(そしてクラッシュします):

[db executeUpdate:@ "INSERT INTO myTable VALUES(?)"、42]; 数値を挿入する適切な方法は、NSNumberオブジェクトに数値をボックス化することです。

[db executeUpdate:@ "INSERT INTO myTable VALUES(?)"、[NSNumber numberWithInt:42]]; または、-execute * WithFormat:バリアントを使用して、NSStringスタイルの置換を使用することもできます。

[db executeUpdateWithFormat:@ "INSERT INTO myTable VALUES(%d)"、42]; 内部的には、-execute * WithFormat:メソッドは適切にボックス化されています。次のパーセント修飾子が認識されます:%@、%c、%s、%d、%D、%i、%u、%U、%hi、%hu、%qi、%qu、%f、%g、% ld、%lu、%lld、および%llu。これら以外の修飾子を使用すると、予測できない結果になります。何らかの理由で、SQLステートメントに%文字を表示する必要がある場合は、%%を使用する必要があります。

4

2 に答える 2

7
NSString *search_text = [NSString stringWithFormat:@"%%%@%%", theSearchQuery];

FMResultSet *rs = [db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE ?", search_text];
于 2011-08-19T22:14:11.340 に答える
4

stringWithFormat:! を使用してクエリを作成しないことを強くお勧めします。FMDB がデータ サニタイズの使用を強制しようとするのには十分な理由があります。ただし、FMDB は入力をボックス化しているため、次のコードでかっこを囲む必要はなく、問題が発生する可能性があります。

[db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE (?)", theSearchQuery];

FMDB が引数を内部的にボックス化する方法がわからないため、括弧なしで単純に引数を追加します。

[db executeQuery:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE ?", theSearchQuery];

それでもうまくいかない場合は、推奨されている FMDB の executeQueryWithFormat: メソッドを使用してみてください。

[db executeQueryWithFormat:@"SELECT * FROM ZARTICLE WHERE ZTITLEDE LIKE %@", theSearchQuery];
于 2011-07-24T16:23:27.367 に答える