I'm trying to get back to adding Oracle support in DatabaseLayer and am coming across 1 big issue. I was able to get all the unit tests passing except the ones with Blobs. It turns out that the OCCI (C++ API) interface uses a 2-step method for adding Blob parameters to the database. Does anyone know if the OCI (C API) is more friendly towards 1-step Blob creation? Before redoing the entire Oracle backend code, I'd like to get a 2nd opinion.
Thanks!
P.S. - After Oracle, I'll try to start on FreeTDS for Sybase/MS SQL Server support.
Oracle support for DatabaseLayer
-
- Earned a small fee
- Posts: 20
- Joined: Mon Jun 19, 2006 6:56 pm
Please leave a message
If you are still interested in getting an answer how to work with BLOBs in Oracle with OCCI, please leave a short messae here. Working with BLOBS cost me hours, but now I seem to have found a way in managing it - so maybe I can help you with your problems.
Thanks for the offer, but someone rewrote the Oracle code to use the OTL interface. I'm not sure at this point if Blobs work with the OTL code, but apparently OCCI is very Oracle version dependent so might have been limiting users ability to connect to a variety of different Oracle servers by going with the OCCI route in the first place.
-
- Earned a small fee
- Posts: 20
- Joined: Mon Jun 19, 2006 6:56 pm
-
- Earned a small fee
- Posts: 20
- Joined: Mon Jun 19, 2006 6:56 pm
Let's start:jb_coder wrote:Could you explain your solution with the OCCI interface? The interfaces are similar enough that it may still be helpful.
We have have got
Code: Select all
Environment *oenv;
Connection *ocon;
Statement *ostm;
Code: Select all
ostm->setAutoCommit (true);
Code: Select all
wxString s_sql = "SELECT value FROM table WHERE ...";
Code: Select all
wxString GetClobValue (wxString s_sql)
{
wxString s_retval = "";
ResultSet *rs = ostm->executeQuery (s_sql.c_str ());
if (rs->next ())
{
Clob cl = rs->getClob (1);
if (cl.isNull ())
{
ostm->closeResultSet (rs);
return "";
}
cl.open (OCCI_LOB_READONLY);
unsigned int cloblen = cl.length ();
if (cloblen > 0)
{
char *buffer = new char[cloblen * 4]; // * 4 is for Unicode-characters, else you'll get runtime errors
unsigned int chars = cl.read (cloblen, (unsigned char*) buffer, cloblen * 4); // * 4 is for Unicode-characters, else you'll get runtime errors
s_retval = buffer;
s_retval = s_retval.Left (chars) + "\0";
#ifndef __WIN32__
buffer = NULL; // this is for Linux environment, else you may get errors, don't know why
#endif
delete (buffer);
}
cl.close ();
}
ostm->closeResultSet (rs);
return s_retval;
// here I normally use a self-written GetSqlText-Function to handle apostrophes
}
Code: Select all
bool SetClobValue (wxString s_table, wxString s_where, wxString s_field, wxString s_contval)
{
wxString s_content = s_contval;
// here I normally use a self-written SetSqlText-Function to handle apostrophes
wxString s_sql = "";
s_sql = "UPDATE " + s_table + " SET " + s_field + " = ' ' WHERE " + s_where;
ostm->executeUpdate (s_sql.c_str ());
ostm->setAutoCommit (false); // you mustn't forget this
s_sql = "SELECT " + s_field + " FROM " + s_table + " WHERE " + s_where + " FOR UPDATE";
ResultSet *rs = ostm->executeQuery (s_sql.c_str ());
if (rs->next ())
{
Clob cl = rs->getClob (1);
cl.open (OCCI_LOB_READWRITE);
unsigned int cloblen = s_content.Length ();
unsigned char *buffer = new unsigned char[cloblen];
buffer = (unsigned char*) (s_content.c_str ());
cl.writeChunk (cloblen, buffer, cloblen, 1);
cl.close ();
ocon->commit ();
#ifndef __WIN32__
buffer = NULL; // this is for Linux environment, else you may get errors, don't know why
#endif
delete (buffer);
}
else
{
wxString s_mess = "Data could not be updated";
ErrorMess (s_mess);
ostm->closeResultSet (rs);
ostm->setAutoCommit (true);
return false;
}
ostm->closeResultSet (rs);
ostm->setAutoCommit (true);
return true;
}
May it be helpful!