2011-02-03 108 views
0

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

文档说:

对于字符串/ 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提出的方法,导致空字符串插入。第一种方法给出了这样的(有点怪异)结果:

database contents

的gvim的窗口显示了它应该是什么样子,顶点屏幕显示了在数据库中结束。

回答

1

(尝试:

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并删除第二行

+0

Vergani缓冲区为零因为没有必要使用空终止符,我不明白这和我发布的第一种方式有什么不同 - 你能解释一下吗?结果是一样的 – 2011-02-03 16:45:35