简体   繁体   English

使用Ocilib时填充字符串缓冲区

[英]Filling a string buffer when using Ocilib

I'm using Ocilib to perform a bulk insert on a Oracle database but I'm having some trouble while filling a string buffer. 我正在使用Ocilib在Oracle数据库上执行批量插入,但是在填充字符串缓冲区时遇到了一些麻烦。

The documentation says: 该文件说:

For string/RAW arrays, the input array MUST BE a contiguous block of data and not an array of pointers. 对于字符串/ RAW数组,输入数组必须是连续的数据块,而不是指针数组。 So to bind an array of 10 elements for a varchar2(30) column, binded variable must be a like array[10][31] 因此,要为varchar2(30)列绑定10个元素的数组,绑定的变量必须是类似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的std :: vector循环时填充字符串缓冲区。 MyClass has a std::string member. MyClass具有std :: string成员。

I'm trying to use the std::string::copy method to copy over the string contents to the buffer. 我正在尝试使用std :: string :: copy方法将字符串内容复制到缓冲区。 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 : PS

The second approach, along the approach proposed by Alessandro Vergani below, results in null strings inserted. 第二种方法与下面的Alessandro Vergani提出的方法一样,导致插入空字符串。 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. gvim窗口显示其外观,而apex屏幕显示最终存储在数据库中的内容。

(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. 我不确定您是否需要添加空终止符:如果没有,请从副本中删除-1并删除第二行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM