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

发布于 2024-10-15 21:07:25 字数 1331 浏览 2 评论 0原文

我正在使用 Ocilib 在 Oracle 数据库上执行批量插入,但在填充时遇到一些问题字符串缓冲区。

文档说:

对于字符串/RAW 数组,输入数组 必须是连续的数据块并且 不是指针数组。所以要绑定 一个包含 10 个元素的数组 varchar2(30) 列,绑定变量 必须是类似数组[10][31]

并且示例继续填充如下所示的缓冲区:

...
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);
}
...

我试图在循环遍历 MyClass 的 std::vector 时填充字符串缓冲区。 MyClass 有一个 std::string 成员。

我正在尝试使用 std::string::copy 方法将字符串内容复制到缓冲区。但我不确切知道如何索引缓冲区来做到这一点。

...
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;
    ...
}
...

第一种方法给了我数据库中的错误数据。第二个让我碰到了空指针。

我做错了什么?

PS

第二种方法(下面由 Alessandro Vergani 提出的方法)会导致插入空字符串。第一种方法给出了这个(有点奇怪)的结果:

databasecontent

gvim 窗口显示了它应该看起来的样子,顶点屏幕显示数据库中的最终内容。

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:

database contents

The gvim window shows what it's supposed to look like, the apex screen shows what ends up in the database.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

简单气质女生网名 2024-10-22 21:07:25

(尝试:

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);
    ...        
}
...

我不确定您是否需要添加空终止符:如果不需要,请从副本中删除 -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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文