2009-04-28 680 views
0

메서드에서 내 응용 프로그램에서 sqlite 문을 다시 사용하려고합니다. 다음은 관련 코드입니다.왜 sqlite3error가 발생합니까?

if(getsets_statement == nil){ 
    const char *sql = "SELECT DISTINCT num,roll FROM mytable WHERE cls like ? and divname like ?"; 
    if(sqlite3_prepare_v2(database, sql, -1, &getsets_statement, NULL) != SQLITE_OK){ 
     NSAssert1(0, @"Error: Failed to prepare stmt with message '%s'", sqlite3_errmsg(database)); 
    }  
} 

sqlite3_bind_text(getsets_statement, 1, [cls UTF8String], -1, SQLITE_TRANSIENT); 
sqlite3_bind_text(getsets_statement, 2, [divname UTF8String], -1, SQLITE_TRANSIENT); 

while(sqlite3_step(getsets_statement) == SQLITE_ROW){ 

    setNumber= sqlite3_column_int(getsets_statement, 0);   

    roll = sqlite3_column_int(getsets_statement, 1); 

    [numArr addObject:[NSNumber numberWithInt:setNumber]]; 
    [rollArr addObject:[NSNumber numberWithInt:roll]]; 
} 

sqlite3_reset(getsets_statement); 

문은 처음 호출 할 때 완벽하게 실행됩니다. 그러나 다음에이 메소드를 호출하면 sqlite3error이됩니다. divnamecls의 값이 존재하지만 (NSLog을 확인했지만)이 오류가 나타나는 이유를 이해할 수 없습니다. 처음으로 bind_text 성명서에 오류가 나타납니다.

이것은 GDB 콘솔

Program received signal: “EXC_BAD_ACCESS”. 
(gdb) where 
#0 0x9041857f in sqlite3Error() 
#1 0x9041acea in vdbeUnbind() 
#2 0x9041b2c8 in bindText() 

어떤 도움에?

+0

cls와 divname이 유효한 개체입니까? –

답변

2

실제로 다른 문제가 없는지 확인하십시오 (데이터베이스가 다른 곳에서 닫혀 있습니까? getsets_statement은 동일한 개체를 가리 킵니까?). 그런 다음 SQLITE_TRANSIENT 대신 NULL 또는 SQLITE___STATIC을 사용해보십시오. [NSString UTF8String]은 해제 할 필요가없는 데이터를 반환하므로 (소멸자가 필요하지 않음), 소멸자가 필요하지 않으며, 함수가 종료 된 후에도 유효하게 유지됩니다. 그러면 언제든지 명령문 실행이 완료됩니다.

+0

문서에서 "다섯 번째 인수가 특수 값 SQLITE_STATIC이면 SQLite는 정보가 정적 인 관리되지 않는 공간에 있다고 가정하고 해제 할 필요가 없습니다 .5 번째 인수의 값이 SQLITE_TRANSIENT이면 SQLite는 sqlite3_bind_ *() 루틴 반환합니다. " 나는 어느 쪽이라도 괜찮을 것이라고 생각하지만 SQLITE_TRANSIENT는 복사가 즉시 이루어지기 때문에 (비록 성능 비용 임에도 불구하고) 확실한 선택이다. –

+1

finalize를 호출하고 있습니다.그것이 문제의 원인이었습니다. 감사. – lostInTransit

+0

@lostInTransit 여기에 귀하의 의견은 내가 가진 동일한 문제에 대한 해결책이기 때문에 귀하의 답변으로 두어야합니다. – gdbj

0

재사용을 시도하기 전에 prepared statement에 sqlite3_resetsqlite3_clear_bindings을 호출해야한다고 생각합니다. 또한 실제로는 반환 코드를 확인해야합니다.

+0

리셋으로 충분하다고 생각했습니다. 어쨌든, 그것은 모든 애플 예제가 사용하는 것입니다. 그러나 나는 그것을 줄 것이다. 감사. – lostInTransit

+0

sqlite3_clear_bindings를 추가하려고 시도했습니다. SQLITE_OK를 리턴합니다. 하지만 여전히 오류가 발생합니다. – lostInTransit

+0

바인딩을 null로 재설정하려면 clear_bindings를 호출해야하지만이 경우에는 명령문에 매개 변수가 2 개 뿐이므로 각 호출에 바인딩되어 있기 때문에이 경우에는 관계가 없습니다. –