SQLite Forum

Help, reading sqlite3_blob_open()
Login

Help, reading sqlite3_blob_open()

(1) By anonymous on 2021-04-28 03:27:49 [link] [source]

I am getting a response code of 1 (The SQLITE_ERROR result code is a generic error code that is used when no other more specific error code is available. )

As I am very new to using sqlite3.c am I doing anything wrong in my code that you can see?  I am not getting a handle but I know (I think I do) that I am parsing the correct values to my function, the file is correct, the table name is correct, the column name is and the row id is correct, I am sure it will be something simple, or not :(

Any suggestions?

Cheers



	char *zErrMsg = NULL;
	sqlite3_blob **ppBlob;
	
               try
		{
		if(!Open())
   		  return;

		_rc = sqlite3_blob_open(_db, UTF8String(_dbSource).c_str(),
					UTF8String(table).c_str(),
					UTF8String(column).c_str(),
					rowId, flags, ppBlob);

		if (_rc != SQLITE_OK)
			{
			String s = zErrMsg;
			sqlite3_free(zErrMsg);
			sqlite3_blob_close(*ppBlob);
			}
		}
	catch (const Exception &e)
		{
                throw Exception(e.Message);
		}
	        finaly:
		{
                CloseV2();
       }

(2) By Larry Brasfield (larrybr) on 2021-04-28 04:20:46 in reply to 1 [link] [source]

One major problem, which I would expect to produce an address fault, is that ppBlob is uninitialized. What you want is code which, excerpted with elisions and string-munging suppressed, would resemble: sqlite3_blob *pBlob = 0; ... _rc = sqlite3_blob_open(_db, zDb, zTable, zColumn, rowId, flags, &pBlob); ... if (_rc == SQLITE_OK ) { // Do stuff with BLOB handle pBlob. sqlite3_blob_close(pBlob); } else { // Moan ... }

Note the type change from ppBlob to pBlob. You are passing a pointer to sqlite3_blob_open so that it can return a BLOB handle as an out parameter. Note also that by initializing that pointer to 0, it can be passed to sqlite3_blob_close harmlessly in case it is not set by the open. (The if guard makes this a redundancy, but your code, as structured, had a real chance of passing a dereference of an uninitialized pointer to sqlite3_blob_close(). )

I have no comment upon the "String s = zErrMsg; sqlite3_free(zErrMsg);" sequence other than to note that its purpose is a puzzle and it would surprise me somewhat if it compiled.

(3) By anonymous on 2021-04-28 04:45:45 in reply to 2 [source]

Thanks Larry,

yep, the String = zErrMsg does not belong, a hasty copy paste from other stuff that actually returned an error message to check _rc value, did not even look at if anything was done with it, so puzzle solved :) but yes it does compile.

Cheers

(4) By anonymous on 2021-04-29 00:28:28 in reply to 2 [link] [source]

Problem still exists after changes but now know a bit more about the issue which I do not understand at all.

This is the message I get from sqlite3_errmsg(_db) "no such table: [E:...my_database_file.db.BlobTable"

Fact of the matter is, the table does exist the file is correctly opened by _rc = sqlite3_open(UTF8String(DBPath).c_str(), &_db); which is the same as the 2nd argument in _blob_open( [..])

This is the modified code I used, so, any ideas as to why _blob_open thinks the table does not exist?

void __fastcall TSQLite::SelectImageSql(String column, String table, sqlite3_int64 rowId, int flags) { sqlite3_blob *pBlob = 0;

if(!Open())

return;

_rc = sqlite3_blob_open(_db, UTF8String(_dbSource).c_str(),
			UTF8String(table).c_str(),
			UTF8String(column).c_str(),
			rowId, flags, &pBlob);
if (_rc == SQLITE_OK)
	{
            //Do my stuff here
	}
else
	{
	sqlite3_blob_close(pBlob);

	_sqliteError.retCode = _rc;
	_sqliteError.errorMsg.sprintf(sqlite3_errmsg(_db));

	if(FSqliteError)  //event handler
	   FSqliteError(this, _sqliteError);

	Close();
	throw Exception(_sqliteError.errorMsg);
	}
}

(5) By Keith Medcalf (kmedcalf) on 2021-04-29 04:12:11 in reply to 4 [link] [source]

The schema name of the database file opened on a connection by the sqlite3_open* API commands is called "main". The temporary datababase is called "temp". If you attach other databases to a connection you can give them whatever schema names you choose.

The error message is pretty explicit: the schema object specified does not exist.

You are confusing the name of the file storing the database in the filesystem with the name of the database schema of that database in the connection.

(6) By anonymous on 2021-04-29 04:36:54 in reply to 5 [link] [source]

Thanks again Keith,

now I understand, I need to read the doc's a bit better, I missed the bit or misunderstood what the zDb parameter wanted.

Cheers