Hi there, I have started using recently SQLite which is pretty great for what I need, (i.e. a scientific application). After going through PostgreSQL, CDB, Tiny CDB and Berkeley DB it feels like coming home when I am looking at the size, speed, number of features and license. :) Anyway I have got a bit of an issue retrieving data from database. I have the code below which works fine until the second fetch_first. It keeps crashing with segmentation fault error. Is there something else that I should do before that, like preparing the stmt again (in documentation it says that is not needed) or clear_bindings (I tried that but I got an error in clear_bindings now and I am thinking that shouldn't really be needed). As a new user I can't seem to find too many C code examples but other than that everything is just great. Is there any difference between execute() & callback() and step() in term of speed? Below is the source code. Any help would be greatly appreciated. Thanks, David db_type *dbo; db_sql_stmt *stmt; const char *object_id; int return_code; char *sql; db_open_read_only("objects.db", dbo, &dbo); sql = "SELECT * FROM Objects ORDER BY ID ASC;"; db_prepare_stmt(dbo, sql, &stmt); return_code = db_fetch_first(dbo, stmt); /* initial call to retrieve first row of data */ while(return_code == SQLITE_ROW) { object_id = (const char *)db_get_column_string(stmt, 0); (printf object_id - the objects are printed fine, one by one) return_code = db_fetch_next(dbo, stmt); /* subsequent calls retrieve the next rows */ } (return_code is now SQLITE_DONE) while(criteria) { (I need to reuse the same SQL statement a couple of times.) db_reset_stmt(dbo, stmt); ********************************************* SEGMENTATION FAULT AT THE NEXT LINE ********************************************* return_code = db_fetch_first(dbo, stmt); /* initial call to retrieve first row of data */ while(return_code == SQLITE_ROW) { object_id = (const char *)db_get_column_string(stmt, 0); (printf object_id ) return_code = db_fetch_next(dbo, stmt); /* subsequent calls retrieve the next rows */ } } db_finalize_stmt(dbo, stmt); /* free statement memory */ db_close(dbo); ________________________________________________________________________ void db_open_read_only(const char *file_name, db_type *db, db_type **pdb) { int return_code; return_code = sqlite3_open_v2(file_name, pdb, SQLITE_OPEN_READONLY, NULL); if(return_code != SQLITE_OK) { /* get the message first and than free the memory before displaying the message */ db_err_msg = sqlite3_errmsg(db); db_close(db); error_message(ERR_FATAL, ERR_ACTION_ABORT, __FILE__, __LINE__, db_err_msg, NULL); } } void db_close(db_type *db) { /* free database pointer memory */ int return_code; return_code = sqlite3_close(db); if(return_code != SQLITE_OK) error_message(ERR_CRITICAL, ERR_ACTION_ABORT, __FILE__, __LINE__, "Unable to close database file.", db_err_msg); } void db_prepare_stmt(db_type *db, const char *sql, db_sql_stmt **pstmt) { int return_code; return_code = sqlite3_prepare_v2(db, sql, strlen(sql), pstmt, NULL); if (return_code != SQLITE_OK) { /* get the message and free memory before displaying the message */ db_err_msg = sqlite3_errmsg(db); db_close(db); error_message(ERR_CRITICAL, ERR_ACTION_ABORT, __FILE__, __LINE__, db_err_msg, NULL); } } void db_reset_stmt(db_type *db, db_sql_stmt *stmt) { int return_code; return_code = sqlite3_reset(stmt); if (return_code != SQLITE_OK) { /* get the message and free memory before displaying the message */ db_err_msg = sqlite3_errmsg(db); db_close(db); error_message(ERR_CRITICAL, ERR_ACTION_ABORT, __FILE__, __LINE__, db_err_msg, NULL); } } void db_finalize_stmt(db_type *db, db_sql_stmt *stmt) { int return_code; return_code = sqlite3_finalize(stmt); if (return_code != SQLITE_OK) { /* get the message and free memory before displaying the message */ db_err_msg = sqlite3_errmsg(db); db_close(db); error_message(ERR_CRITICAL, ERR_ACTION_ABORT, __FILE__, __LINE__, db_err_msg, NULL); } } int db_fetch_first(db_type *db, db_sql_stmt *stmt) { int return_code; int retry_count = 0; /* counter that indicates how many times we have retried the same operation */ return_code = sqlite3_step(stmt); /* check if the returned code indicates low processing resources and if true retry the operation */ while((return_code == SQLITE_BUSY) && (retry_count < 3)) { sqlite3_sleep(500); /* 500 milliseconds or rounded up to 1 second if not supported */ retry_count++; return_code = sqlite3_step(stmt); } return return_code; } int db_fetch_next(db_type *db, db_sql_stmt *stmt) { int return_code; int retry_count = 0; /* counter that indicates how many times we have retried the same operation */ return_code = sqlite3_step(stmt); /* check if the returned code indicates low processing resources and if true retry the operation */ while((return_code == SQLITE_BUSY) && (retry_count < 3)) { sqlite3_sleep(500); /* 500 milliseconds or rounded up to 1 second if not supported */ retry_count++; return_code = sqlite3_step(stmt); } return return_code; } const unsigned char *db_get_column_string(db_sql_stmt *stmt, int column_position) { static const unsigned char *buffer = NULL; db_type *db = NULL; buffer = sqlite3_column_text(stmt, column_position); /* check if there was an error or NULL is the correct value returned */ if (buffer == NULL) { db = db_get_handle(stmt); /* retrieve associated database handle for the current statement */ if (sqlite3_errcode(db) == SQLITE_NOMEM) /* an error occured*/ { /* get the message and free memory before displaying the message */ db_err_msg = sqlite3_errmsg(db); db_close(db); error_message(ERR_CRITICAL, ERR_ACTION_ABORT, __FILE__, __LINE__, db_err_msg, NULL); } } return buffer; }
--------------------------------- Be a better pen pal. Text or chat with friends inside Yahoo! Mail. See how.