问题
I'm using Ocilib to perform a bulk insert on a Oracle database but I'm having some trouble while filling a string buffer.
The documentation says:
For string/RAW arrays, the input array MUST BE a contiguous block of data and not an array of pointers. So to bind an array of 10 elements for a varchar2(30) column, binded variable must be a like array[10][31]
And a sample proceeds to fill a buffer like this:
...
char tab_str[1000][21];
...
OCI_BindArrayOfStrings(st, ":s", (char*) tab_str, 20, 0);
...
for(i=0;i<1000;i++)
{
sprintf(tab_str[i],"Name %d",i+1);
}
...
I'm trying to fill the string buffer while looping through a std::vector of MyClass. MyClass has a std::string member.
I'm trying to use the std::string::copy method to copy over the string contents to the buffer. But I don't know exactly how to index the buffer to do it.
...
OCI_BindArrayOfStrings(st, ":f2", NULL, VCHAR_SIZE, 0);
char** vc_buffer = (char**)OCI_BindGetData(OCI_GetBind(st, 2));
...
int i = 0;
for(vector<MyClass>::const_iterator it = myVec.begin(); it != myVec.end(); ++it)
{
/* 1st try */ it->m_string.copy((vc_buffer + (i * VCHAR_SIZE)), VCHAR_SIZE);
/* 2nd try */ it->m_string.copy(vc_buffer[i], VCHAR_SIZE);
++i;
...
}
...
The first way gives me buggy data in the database. The second makes me hit a null pointer.
What I'm doing wrong?
PS:
The second approach, along the approach proposed by Alessandro Vergani below, results in null strings inserted. The first approach gives this (somewhat bizarre) result:
The gvim window shows what it's supposed to look like, the apex screen shows what ends up in the database.
回答1:
(Try:
std::vector<char> tab_str(myVec.size() * (VCHAR_SIZE + 1));
...
OCI_BindArrayOfStrings(st, ":s", &tab_str[0], VCHAR_SIZE, 0);
...
int offset = 0;
for(vector<MyClass>::const_iterator it = myVec.begin(); it != myVec.end(); ++it, offset += VCHAR_SIZE)
{
it->m_string.copy(&tab_str[offset], VCHAR_SIZE);
...
}
...
I'm not sure you need to add the null terminator: if not, remove the -1
from the copy and remove the second line.
来源:https://stackoverflow.com/questions/4887792/filling-a-string-buffer-when-using-ocilib