0

異なる測定単位間でコンバーターのようなアプリを構築しようとしています。現在、私は SQLite を使用しており、さまざまな単位と対応するレートを含むテーブルがあります。

アプリ内には、選択した単位に応じてレート値を取得する次の関数があります。

+(float)rateFrom:(NSString *)from to:(NSString *)to{
    if (sqlite3_open([sqlPath UTF8String], &database) == SQLITE_OK) {

        const char *sql = [[NSString stringWithFormat:@"SELECT %@ FROM Units WHERE code = '%@'", to, from] UTF8String];
        sqlite3_stmt *selectstmt;

        if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {
            return (float)sqlite3_column_double(selectstmt, 0);
        }
    }
    else{
        sqlite3_close(database);
    }
    return -1;
}

問題は還元率が0.00

作成したクエリをターミナル ウィンドウで直接試したところ、正しい値が返されました

私も試してみましたがNSNumberinitWithFloat:成功しませんでした。

ここで私が間違っていることを誰かに説明してもらえますか?

前もって感謝します。

4

1 に答える 1

1

実際にクエリを実行することはありません。クエリを「コンパイル」しますが、実際には実行sqlite3_prepare_v2しません。おそらく、実際にクエリを実行するために呼び出したいと思うでしょう。コンパイルされたステートメントも呼び出していないため、このコードでメモリリークも発生しています。これは役立つかもしれません:sqlite3_stepsqlite3_finalize

+ (float)rateFrom:(NSString *)from to:(NSString *)to
{
    float retVal = -1;
    if (sqlite3_open([sqlPath UTF8String], &database) == SQLITE_OK) {

        const char *sql = [[NSString stringWithFormat:@"SELECT %@ FROM Units WHERE code = '%@'", to, from] UTF8String];
        sqlite3_stmt *selectstmt;

        if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK && 
           sqlite3_step(selectstmt) == SQLITE_ROW) {
            retVal = (float)sqlite3_column_double(selectstmt, 0);
        }
        if (selectstmt) {
            sqlite3_finalize(selectstmt);
        }
        sqlite3_close(database);
        database = NULL;
    }

    return retVal;
}

また、文字列がユーザー入力に出入りする場合、toSQLfromインジェクション攻撃に対して脆弱であるため、文字列をクエリで文字通り使用したくないでしょう。

SQLite API の優れた Objective-C ラッパーであるFMDBの使用を検討することもできます。

于 2013-09-22T22:13:16.257 に答える