If you have ever used a database from within a
programming language, SQLite database manipulation using C should seem
intuitive. You open the database. You create a prepared statement
containing a SQL string. That statement might have one or more
parameters you bind values to. After binding, you execute the statement.
If the statement returns results, you loop through each record and load
the record’s column values into your program’s variables. After looping
through all records, you finalize the statement, and, if you are
finished with the database, you close the database. The steps are
similar for most languages and databases.
Opening the Database
You open a database
using the sqlite3_open, sqlite_open16, or sqlite3_open_v2 commands. This
article uses the sqlite3_open command exclusively. The sqlite3_open
command takes a database filename as a UTF-8 string and opens the
database. Listing 1, taken from the SQLite’s online documentation, lists the sqlite_open3 method signature.
Listing 1. The sqlite3_open method signature (from SQLite online documentation)
int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ );
|
The method returns an integer as the method’s success or failure code. Listing 2, from the SQLite online documentation, lists several common result codes.
Listing 2. SQLite return codes (taken from SQLite online documentation)
#define SQLITE_OK 0 /* Successful result */ #define SQLITE_ERROR 1 /* SQL error or missing database */ #define SQLITE_READONLY 8 /* Attempt to write a readonly database */ #define SQLITE_INTERRUPT 9 /* Operation terminated by #define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_MISMATCH 20 /* Data type mismatch */ #define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ #define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
|
Statements, Preparing Statements, and Executing Statements
There
are two primary ways of executing SQL statements using SQLite’s C
interface. One method is the sqlite3_exec method. Although a powerful
method, it is more advanced C programming, and so this article uses the
sqlite3_stmt structure and the sqlite3_prepare_v2 and sqlite3_step
statements instead of the sqlite3_exec function.
The SQLite sqlite3_stmt
The sqlite3_stmt encapsulates a
SQL statement. For instance, “select * from photos” is a SQL statement.
In your program, you encapsulate this SQL string using a statement. For
instance, the following code snippet illustrates creating a SQL string,
initializing a statement, and loading the statement (Listing 3).
Listing 3. Using a sqlite3_stmt in a C program
const char *sqlselect = "SELECT id,name,photo FROM photos"; static sqlite3_stmt *statement = nil; sqlite3_prepare_v2(database, sqlselect, -1, &statement, NULL);
|
The SQLite sqlite3_prepare_v2 Method
You load a SQL string into a
statement using sqlite3_prepare methods. The prepare methods are
sqlite3_prepare, sqlite3_prepare_v2, sqlite3_prepare_16, and
sqlite3_prepare16_v2. This article uses only the sqlite3_prepare_v2
method. Notice the prepare statement takes a C string, not an NString,
but getting the C string from an NString is not difficult—simply call
the NSString’s UTF8String method. The sqlite3_prepare_v2 method’s
signature is in Listing 4.
Notice, like the open statements, the prepare statement returns an
integer result code you should check when calling the method.
Listing 4. The sqlite3_prepare_v2 method signature (taken from the SQLite online documentation)
int sqlite3_prepare_v2( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ );
|
After preparing the statement, you execute it and step through the results.
The SQLite sqlite3_step Method
The
sqlite3_step method executes a prepared statement. You must call this
method at least once. For instance, when calling insert or update, you
call sqlite3_step once. You only call it once because these statements
do not result in a record set being returned from the database. When
selecting data, you typically call this method multiple times until you
receive no more results. The following is the method’s signature.
int sqlite3_step(sqlite3_stmt*);
Like the other SQLite methods, this method returns a response code you should check after calling the method.