2013-01-23 3 views
1

SQL 쿼리를 준비하고 sqlite db에 대해 실행하는 함수를 작성하고 있습니다. 나는 테이블에 값을 삽입하는 쿼리를 사용하고, 쿼리는이sqlite 쿼리가 준비되지 않았습니다. 값이 없습니다.

"insert into files values (?, ?, ?, ?, ?, 0)"; 

행이 삽입되지만 텍스트 필드의 모든 값이 0으로 처음 5 개 필드는있는 마지막 필드를 제외하고 비어있는 것 같습니다 내 문자열 인수에 물음표를 교체되지 않는 이유의 전체 기능이 calller에 의해 스택에 생성 below.The 목록이 표시됩니다

// If I hard code a value for value.data() then the row is inserted correctly with my hardcoded data, the exact line is below 
    status = sqlite3_bind_text(ppStmt, index, /* if I hardcode it works*/ value.data(), -1, SQLITE_STATIC); 

텍스트를 입력, 나는 확실하지 오전, 하드 사람이없는 ..하지만 일 오류 코드가 반환됩니다.

//db is already open before I call this 
void MediaCache::prepareAndExecuteQuery(string query, list<string> args) 
{ 

    sqlite3_stmt *ppStmt = 0; 
    const char **pzTail = 0; 
    int status = 0; 

    if(sqlite3_prepare_v2(db, query.data(), query.length(), &ppStmt, pzTail) != SQLITE_OK) 
    { 
     string error = sqlite3_errmsg(db); 
     //throw an exception 
    } 

    if(ppStmt) 
    { 

     list<string>::iterator current = args.begin(); 
     int index = 1; 

     for(current = args.begin() ; current != args.end(); current++) 
     { 
      string value = *current;    
      status = sqlite3_bind_text(ppStmt, index, value.data(), -1, SQLITE_STATIC); 

      if(status != SQLITE_OK) 
      { 
       //log error; 
      } 

      index++; 
     } 

     status = sqlite3_step(ppStmt); 
     status = sqlite3_finalize(ppStmt); 
     //sqlite3_exec(db, "COMMIT", NULL, NULL, NULL); 
    } 
    else 
    { 
     //ppStmt is null 
     //throw an exception 
    } 

} 
나는이 문제를 의심
+0

0-4 열의 데이터 유형은 무엇입니까? ? – Arpit

+0

유형이 처음 5 개 필드의 경우 TEXT입니다. – Ahmed

+0

이전 질문에서 이미 답변했습니다. 인수 바인딩 방법 [여기] (http://stackoverflow.com/questions/14483120/how-to-prepare-a-c-string-for-sql-query/14483389#14483389)을 참조하십시오. – m0skit0

답변

2

은 여기에 있습니다 : 명령문의 실행이 일어나기 전에이 경우 value에서

string value = *current;    
status = sqlite3_bind_text(ppStmt, index, value.data(), -1, SQLITE_STATIC); 

이 범위를 벗어나. 따라서 sqlite3_bind_text에 주어진 포인터는 더 이상 유효하지 않습니다. "수정"하려면 SQLITE_TRANSIENT를 사용할 수 있습니다. SQLITE_TRANSIENT는 라이브러리가 반환하기 전에 데이터의 자체 복사본을 만들도록합니다.

또한 C++ 11을 사용하지 않는 경우 string::data()이 NULL 종료가 보장됩니다.이 경우 -1 매개 변수가 잘못되었을 수 있습니다. 대신 value.length()이되어야합니다.

+0

Mark,이 경우 복사본 대신 참조 또는 const 참조를 사용 하시겠습니까? 그리고 나는 적어도'c_str()'과 같은 것이 문자열 상수에 더 적절하다고 생각합니다. – WhozCraig

+0

@WhozCraig : (* 현재) .data()를 사용하는 것이 괜찮을 것이라고 생각합니다. 문자열이 실행되기 전에 변경되지 않는 한이 포인터는 유효 할 것이라고 믿습니다. –

+0

감사 마크, SQLite_TRANSIENT 또는 current-> data()를 사용하여 SQLITE_STATIC 작업을 수행하면 올바른 값이 올바른 값으로 실행되기 전에 범위를 벗어납니다. c_str()은 null이 C 문자열을 종료한다는 것을 보장합니까? Windows Visual Studio에서 개발하고 있지만 결국 Mac의 xode에서도 컴파일됩니다. – Ahmed

관련 문제