You can get results without using a callback using something like this:
Local StatementHandle:int
Local Tail: Byte Ptr
' Executes the Command
Local ErrorCode:int = SQLite3_Prepare(db, Command, Command.Length, StatementHandle, Varptr(Tail))
' Make sure it executed correctly
If ErrorCode = 0 then
' The Tail contains any part of the Command which wasn't executed
' I've never had reason to use this myself
Local UnusedSQL:string = string.FromCString(Tail)
' Loop round all the rows in the resulting data set
Local Done = False
Repeat
' Move to the next row in the data set
Local StepResult:Int = SQLite3_Step(StatementHandle)
Select StepResult
' Step has found the next row
Case 100
' If for example the first column is an integer
Print SQLite3_Column_Int(StatementHandle, 0)
' The next column is a string
Print SQLite3_Column_Text(StatementHandle, 1)
' The next column is a float
Print SQLite3_Column_Double(StatementHandle, 2)
' Step has reached the end of the data set
Case 101
Done = true
' Step has resulted in an error
Default
RuntimeError(StepResult)
End Select
Until Done
' Closes the data set
SQLite3_Finalize(StatementHandle)
End If
Note that this code has been extracted from SQLite wrapper classes I was working on with the BMX v1.09 demo. The demo expired months ago and I haven't bought BMX yet so I haven't been able to finish the wrapper classes or test this code :-)
I've been planning to release my SQLite wrapper classes once I've bought BMX and finished them off :-)
Edit: As for using SQLite in games - I'm using it (in Blitz3D) for storing player profiles (options, high scores, stats etc) in Eridani. I guess I could use it for storing level data too, but then I'd have to write an editor for it and I find it much easier to just put that stuff into XML files.