2014-02-06 2 views
1

DB에서 데이터를 가져 오려고하는데 문제가 있습니다.SQLite 데이터베이스에서 값을 가져 오는 방법

여기 내 코드입니다 :

NSString *action=[[NSString alloc]init]; 
NSString *queryStatement = [NSString stringWithFormat:@"SELECT ACTIONNAME FROM ACTIONS WHERE ACTIONSYMBOL = '%@'", symbol]; 

// Prepare the query for execution 
sqlite3_stmt *statement; 
if (sqlite3_prepare_v2(database, [queryStatement UTF8String], -1, &statement, NULL) == SQLITE_OK) 
{ 
    // Create a new address from the found row 
    while (sqlite3_step(statement) == SQLITE_ROW) { 
     action = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 1)]; // fails on this line 
    } 
    sqlite3_finalize(statement); 

    return action; 
} 

(매개 변수 외부에서 오는 기호)

내가 이것을 실행하면, 그것은 sqlite3_column_text 결과 stringWithUTF8String에 대한 호출과 라인에 실패합니다. 당신은 아마 NSMutableArray의 결과를 수집 할

+2

FMDatabase 프레임 워크를 사용하는 것이 좋습니다. sqlite의 훌륭한 래퍼입니다. – etolstoy

답변

0

sqlite3_column_text으로 전화하면 1 색인이 사용되지만 0부터 시작하는 색인이 사용됩니다. 1 대신 0을 사용하십시오. 라는 SQLite sqlite_column_XXX documentation, 참조 :

결과 집합의 가장 왼쪽 열은 인덱스 당신이 그것을 NULL 값을 전달하면 예외가 발생 stringWithUTF8String부터 0

그런데

을 가지고

계속 진행하기 전에 sqlite3_column_textNULL이 아닌 경우 결과를 확인하고 오류를 정상적으로 처리하는 것이 더 안전합니다. 또한, 당신과 같이, sqlite3_stepsqlite3_prepare_v2 오류를 검사 할 수 있습니다 : 위가 있듯이

NSString *queryStatement = [NSString stringWithFormat:@"SELECT ACTIONNAME FROM ACTIONS WHERE ACTIONSYMBOL = '%@'", symbol]; // note, it can be dangerous to use `stringWithFormat` to build SQL; better to use `?` placeholders in your SQL and then use `sqlite3_bind_text` to bind the `symbol` value with the `?` placeholder 

if (sqlite3_prepare_v2(database, [queryStatement UTF8String], -1, &statement, NULL) == SQLITE_OK) 
{ 
    int rc; 
    while ((rc = sqlite3_step(statement)) == SQLITE_ROW) { 
     const unsigned char *value = sqlite3_column_text(statement, 0); // use zero 

     if (value) { 
      NSString *action = [NSString stringWithUTF8String:(const char *)value]; 

      // now do whatever you want with `action`, e.g. add it to an array or what 
     } else { 
      // handle the error (or NULL value) gracefully here 
     } 

     // make sure to check for errors in `sqlite3_step` 

     if (rc != SQLITE_DONE) 
     { 
      NSLog(@"%s: sqlite3_step failed: %s", __FUNCTION__, sqlite3_errmsg(database)); 
     } 
    } 
} 
else 
{ 
    NSLog(@"%s: sqlite3_prepare_v2 failed: %s", __FUNCTION__, sqlite3_errmsg(database)); 
} 

덧붙여, 올바르게 오류 검사를 모두 수행하는 것은 조금 복잡합니다. FMDB가 유용 위의 단순화 할 수있는 곳이다 (db 개방되었습니다 FMDatabase 대상 임) :

FMResultSet *rs = [db executeQuery:@"SELECT ACTIONNAME FROM ACTIONS WHERE ACTIONSYMBOL = ?", symbol]; 
if (!rs) { 
    NSLog(@"%s: executeQuery failed: %@", __FUNCTION__, [db lastErrorMessage]); 
    return; 
} 

while ([rs next]) { 
    NSString *action = [rs stringForColumnIndex:0]; 

    // do whatever you want with `action` here 
} 

[rs close]; 

그리고 당신은 오히려 당신의 SQL을 구축하는 stringWithFormat를 사용하는 것보다 (? 자리 표시자를 사용하는 경우 위험한) FMDB를 사용하면 얻을 수있는 이점이 훨씬 더 강력합니다.

+0

고마워요 !!!! 그것은 그 것이었다! – user3245831

2

:

NSMutableArray *action = [[NSMutableArray alloc] init]; 
... 

while (sqlite3_step(statement) == SQLITE_ROW) { 
    [action addObject:[NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)]]; 
} 

... 

그런 다음 무엇을 볼 수 있습니다 나중에 수집 :

for (NSString *s in action) { 
    NSLog(@"%@", s); 
} 

편집이 바와 같이 @ 롭의 대답은 지적 첫 번째 열은 0이며 1이 아닙니다.

+0

아니요 결과 하나의 데이터 만 있습니다 – user3245831

+0

왜 그가 다중 값을 얻을 것이라고 생각합니까? 내 생각에, 너는 틀렸어. – etolstoy

+0

@ user3245831 왜 'while' 루프가 필요합니까? – trojanfoe

관련 문제