iPhone SQLite数据库读写

时间:2010-08-06 00:45:31

标签: iphone objective-c database xcode sqlite

所以我试图在一个iPhone应用程序中使用SQLite,而我正在使用sqlite3库。我能够访问数据库甚至进行查询;事实上,查询访问确切的数据,但由于某种原因,我得到的字符串是一个长整数,而不是我正在寻找的字符串。这是数据库和代码:

Filename: Package.sql
Table Lessons
LessonID VARCHAR(64) Primary Key | LessonName VARCHAR(100) | EntryDate (DATETIME) | Chrono VARCHAR (20) 
bfow02nso9xjdo40wksbfkekakoe29ak | Learning The History    | 2010-08-05 16:24:35  | 0001

和iPhone代码

...
-(NSString *)getRow:(NSString *)tablename where:(NSString *)column equals:(NSString *)value {

  const char *query = [[[[[[[@"SELECT * FROM `" stringByAppendingString:tablename] stringByAppendingString:@"` WHERE `"] stringByAppendingString:column] stringByAppendingString:@"` = '"] stringByAppendingString:value] stringByAppendingString:@"';"] cStringUsingEncoding:NSUTF8StringEncoding];

  NSString *result;

  if(sqlite3_open([dbpath UTF8String], &database) == SQLITE_OK) {

    sqlite3_stmt *compiledQuery;

    if(sqlite3_prepare_v2(database, query, -1, &compiledQuery, NULL) == SQLITE_OK) {

      while(sqlite3_step(compiledQuery) == SQLITE_ROW) {

        NSString *str_temp = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledQuery, 2)];

        result = str_temp;
        
      }

      sqlite3_finalize(compiledQuery);

    }

    sqlite3_close(database);

  }
 
  return result;

}
...

代码执行时:

  CDatabase *db = [[CDatabase alloc]initWithDatabase:@"Package.sql"];
  NSString *result = [db getRow:@"Lessons" where:@"Chrono" equals:@"0001"];

返回值NSString * result的值为“1,364,111”。它为什么这样做?它应该是“学习历史”

2 个答案:

答案 0 :(得分:2)

您确定您的任何SQLite调用都成功吗?您应该将result初始化为nil,以便在发现任何错误时您的函数返回nil

您的代码有三个(可能是相关的)问题:

  1. sqlite3_column_text的索引应为零;你正在传递2,这应该引用第三列。你可能想要通过1。来自the docs

      

    ...第二个参数是应该返回信息的列的索引。结果集的最左列具有索引0。

  2. 你真的不应该使用SELECT *。指定所需的列!

  3. 您应该通过绑定值来专门化您的查询,而不是通过连接字符串!您的代码充斥着SQL注入的可能性(更不用说错误的查询)。

  4. 例如(没有错误检查):

    const char *query = "SELECT * FROM ? WHERE ?=?";
    sqlite3_stmt *compiledQuery;
    sqlite3_prepare_v2(database, query, -1, &compiledQuery, NULL);
    sqlite3_bind_text(compiledQuery, 1, "Lessons", -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(compiledQuery, 2, "Chrono", -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(compiledQuery, 3, "0001", -1, SQLITE_TRANSIENT);
    

    请注意,此处的索引是基于1的(我不知道他们为什么这样做)。来自docs

      

    第二个参数是要设置的SQL参数的索引。最左边的SQL参数的索引为1.

答案 1 :(得分:0)

哈哈哎呀我意识到我只是使用%d字符串格式将字符串显示为数据格式。当我把它改为%@时,我得到了字符串格式