Заполнение строкового буфера при использовании Ocilib - PullRequest
0 голосов
/ 03 февраля 2011

Я использую 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);
}
...

Я пытаюсь заполнить строковый буфер во время цикла через std :: vector MyClass. 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 :

Второй подход, наряду с подходом, предложенным Алессандро Вергани ниже, приводит к вставке нулевых строк. Первый подход дает такой (несколько странный) результат:

database contents

Окно gvim показывает, как оно должно выглядеть, на экране apex отображается то, что заканчивается в базе данных.

1 Ответ

1 голос
/ 03 февраля 2011

(Попробуйте:

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 из копии и удалите вторую строку.

...