Invalid BLOB ID on insert into Firebird 2.5 - insert

I am trying to insert some binary data into a Firebird BLOB field using the API from a C++ application. My code is basically as follows (error handling omitted), after the official Firebird API manual:
extern db_conn_t global_db;
extern db_txn_t global_txn;
extern db_stmt_t global_stmt;
#define mydb (global_db.db_conn)
#define mytr (global_txn.dt_txn)
#define mystmt (global_stmt.ds_stmt)
#define status_vector (global_db.db_status)
isc_blob_handle hblob;
ISC_QUAD blobid;
XSQLDA *pinsqlda;
short flag[NUM_FIELDS];
memset (&flag[0], 0, NUM_FIELDS*sizeof(short));
hblob = NULL;
memset (&blobid, 0, sizeof(blobid));
isc_create_blob2(status_vector, &mydb, &mytr, &hblob, &blobid, 0, NULL);
isc_put_segment(status_vector, &hblob, payload_len, (char*)payload);
isc_close_blob(status_vector, &hblob);
pinsqlda = (XSQLDA *)calloc(1, XSQLDA_LENGTH(NUM_FIELDS));
...
pinsqlda->sqlvar[4].sqldata = (char *)&(blobid);
pinsqlda->sqlvar[4].sqltype = SQL_BLOB + 1;
pinsqlda->sqlvar[4].sqllen = sizeof(blobid);
pinsqlda->sqlvar[4].sqlind = &flag[4];
...
Then the query is submitted in the same way as many other instances elsewhere in the application, so I'm confident there is no problem there.
The blob creation completes with no error, but when the query is submitted, the returned error code is "invalid BLOB ID".
Can anyone see what I am doing wrong?
Update (from comment)
I just re-ordered my statements to put the blob creation after the definition of the XSQLDA structure and calls to isc_dsql_allocate_statement and isc_dsql_prepare, and lo! it works without error. So my immediate problem is solved, but I'd still appreciate knowing what exactly was going wrong.

You don't show statement prepare / execute nor the transaction start which is relevant for this problem: The error you post is usually caused by creating the blob in a different transaction than the one you use to execute the insert or update: as long as a blob id hasn't been linked to a table, it is not visible in other transactions.

Related

What is the meaning of "Fb::Error: A transaction has already been started"

I have a Ruby application that crashes sometimes with this error message:
Fb::Error: A transaction has already been started)
I'm now wondering what this message means. I searched a little bit and I read that Firebird is not supporting nested transactions. Could the message hint to this? If not, what else could this mean?
This is not a Firebird error message. It is an error message in the driver you're using. Specifically here:
static void fb_connection_transaction_start(struct FbConnection *fb_connection, VALUE opt)
{
char *tpb = 0;
long tpb_len;
if (fb_connection->transact) {
rb_raise(rb_eFbError, "A transaction has been already started");
}
if (!NIL_P(opt)) {
tpb = trans_parseopts(opt, &tpb_len);
} else {
tpb_len = 0;
tpb = NULL;
}
isc_start_transaction(fb_connection->isc_status, &fb_connection->transact, 1, &fb_connection->db, tpb_len, tpb);
xfree(tpb);
fb_error_check(fb_connection->isc_status);
}
Without in-depth familiarity with this driver, I'm guessing the problem is that you're trying to start a transaction on a connection that already has an active transaction.
Firebird itself supports multiple parallel transactions on a single connection, and it supports nested transactions in the form of SQL standard savepoints, but it looks like the driver you're using doesn't support this.
The solution (or workaround) would seem to be to either not start a transaction when you already have an active transaction, or to first commit or rollback an existing transaction before starting a new one.

Windows crash in ChangeServiceConfig2

I'm having a problem with ChangeServiceConfig2(...SERVICE_CONFIG_TRIGGER_INFO...)
Relevant code:
WCHAR test[] = L"TEST12";
SERVICE_TRIGGER_SPECIFIC_DATA_ITEM stdata {
SERVICE_TRIGGER_DATA_TYPE_STRING,
wcslen(test)*sizeof(WCHAR),
reinterpret_cast<BYTE*>(test)
};
SERVICE_TRIGGER st {
SERVICE_TRIGGER_TYPE_NETWORK_ENDPOINT,
SERVICE_TRIGGER_ACTION_SERVICE_START,
const_cast<GUID*>(&NAMED_PIPE_EVENT_GUID),
1, &stdata
};
ChangeServiceConfig2(Service, SERVICE_CONFIG_TRIGGER_INFO, &st);
This causes an Access Violation on address 00000009, so clearly an unchecked null pointer. And it's not a null pointer in st or stdata. The address 00000009 does not depend on the length of test[].
Stack dump:
rpcrt4.dll!NdrpEmbeddedRepeatPointerBufferSize()
rpcrt4.dll!NdrConformantArrayBufferSize()
rpcrt4.dll!NdrSimpleStructBufferSize()
rpcrt4.dll!NdrpUnionBufferSize()
rpcrt4.dll!_NdrNonEncapsulatedUnionBufferSize#12()
rpcrt4.dll!NdrComplexStructBufferSize()
rpcrt4.dll!NdrClientCall2() rpcrt4.dll!_NdrClientCall4()
sechost.dll!ChangeServiceConfig2W()
The Service member is not the problem, or ChangeServiceConfig2 itself: I can set the service description via ChangeServiceConfig2(Service, SERVICE_CONFIG_DESCRIPTION, &desc);. The problem appears to be in the parsing of SERVICE_TRIGGER. Named Pipe service triggers apparently work for the Remote Registry service, so it's not fundamentally broken.
Q: which part of my SERVICE_TRIGGER is wrong?
Obviously there is at least one bug in Windows; at the very least it fails in parameter validation.
The SERVICE_TRIGGER object is correct, but ChangeServiceConfig2 wants a SERVICE_TRIGGER_INFO. Simple solution: wrap st using SERVICE_TRIGGER_INFO sti{ 1, &st, NULL };

java.sql.SQLException: Missing defines

We have a very simple Java code which executes an Oracle stored procedure using CallableStatement API. An Oracle stored procedure doesn't have an OUTPUT parameter defined, however in the Java Code we are trying to register an OUT parameter and retrieve it :
cs = cnDBCon.prepareCall("{call "+strStoredProcedureName+ "}");
cs.registerOutParameter(1, Types.NUMERIC);
cs.execute();
int isOk = cs.getInt(1);
According to Java API ( https://docs.oracle.com/javase/8/docs/api/java/sql/CallableStatement.html#getInt-int- ) when a return value is SQL NULL, the result is 0.
It worked perfectly fine when we were running on Java7/WebLogic 12.1.3. Since we switched to Java8/WebLogic 12.2.1 we started to get the error :
java.sql.SQLException: Missing defines
at oracle.jdbc.driver.Accessor.isNull(Accessor.java:744)
at oracle.jdbc.driver.NumberCommonAccessor.getInt(NumberCommonAccessor.java:73)
at oracle.jdbc.driver.OracleCallableStatement.getInt(OracleCallableStatement.java:1815)
at oracle.jdbc.driver.OracleCallableStatementWrapper.getInt(OracleCallableStatementWrapper.java:780)
at weblogic.jdbc.wrapper.CallableStatement_oracle_jdbc_driver_OracleCallableStatementWrapper.getInt(Unknown Source)
The obvious choice is to update the stored procedure or java code, but I am wondering about the reason the behavior changed. Is it a more strict JDBC driver?

Boost event logger

http://boost-log.sourceforge.net/libs/log/doc/html/log/detailed/sink_backends.html
In this page there is sample code to initialize boost windows event backends,
but when I run it it gives memory error at first line.
void init_logging()
{
// Create an event log sink
boost::shared_ptr< sink_t > sink(new sink_t());
sink->set_formatter
(
expr::format("%1%: [%2%] - %3%")
% expr::attr< unsigned int >("LineID")
% expr::attr< boost::posix_time::ptime >("TimeStamp")
% expr::smessage
);
// We'll have to map our custom levels to the event log event types
sinks::event_log::custom_event_type_mapping< severity_level > mapping("Severity");
mapping[normal] = sinks::event_log::info;
mapping[warning] = sinks::event_log::warning;
mapping[error] = sinks::event_log::error;
sink->locked_backend()->set_event_type_mapper(mapping);
// Add the sink to the core
logging::core::get()->add_sink(sink);
}
Here it fails to create sink_t object.
boost::shared_ptr< sink_t > sink(new sink_t());
Any idea what is the problem and how can I solve this?
Also If you know any other source that I can learn using boost event logging please write.
No answer yet...
But I have found a solution in a blog by Timo Geusch.
http://www.lonecpluspluscoder.com/2011/01/boost-log-preventing-the-unhandled-exception-in-windows-7-when-attempting-to-log-to-the-event-log/
The reason for this problem was that the registry key in HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog\ that the application needs access to both has to be present (if you’re not administrator, you don’t have the privileges to create it) and the user who runs the application also needs to be able to both read and write to it.

Error while uploading image to database

When I am trying to upload an Image using below code, I am getting following error : java.sql.SQLException: ORA-01460: unimplemented or unreasonable conversion requested
File image = new File("D:/"+fileName);
preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1,"Ayush");
fis = new FileInputStream(image);
preparedStatement.setBinaryStream(2, (InputStream)fis, (int)(image.length()));
int s = preparedStatement.executeUpdate();
if(s>0) {
System.out.println("Uploaded successfully !");
flag = true;
}
else {
System.out.println("unsucessfull to upload image.");
flag = false;
}
Please help me out.
DB Script :
CREATE TABLE ESTMT_SAVE_IMAGE
(
NAME VARCHAR2(50),
IMAGE BLOB
)
Its first cause is incompatible conversion but after seeing your DB script, I assume that you are not doing any conversion in your script.
There are other reported causes of the ORA-01460 as well:
Incompatible character sets can cause an ORA-01460
Using SQL Developer, attempting to pass a string to a bind variable value in excess of 4000 bytes can result in an ORA-01460
With ODP, users moving from the 10.2 client and 10.2 ODP to the 11.1 client and 11.1.0.6.10 ODP reported an ORA-01460 error. This was a bug that should be fixed by patching ODP to the most recent version.
Please see this

Resources