Как обрабатывать длинные строки с ODBC? - PullRequest
0 голосов
/ 28 февраля 2012

Я использую ODBC SQLGetData для извлечения строковых данных, используя 256-байтовый буфер по умолчанию.Если буфер слишком короткий, я выделяю новый буфер, достаточно большой для строки, и снова вызываю SQLGetData ().

Кажется, что вызов этого параметра во второй раз возвращает только то, что осталось после последнего вызова,а не все поле.

Есть ли способ «сбросить» это поведение, чтобы SQLGetData возвращала все поле во второй буфер?

char buffer[256];
SQLLEN sizeNeeded = 0;

SQLRETURN ret = SQLGetData(_statement, _columnIndex, SQL_C_CHAR, (SQLCHAR*)buffer, sizeof(buffer), &sizeNeeded);

if(ret == SQL_SUCCESS)
{
    return std::string(buffer);
}
else if(ret == SQL_SUCCESS_WITH_INFO)
{
    std::auto_ptr<char> largeBuffer(new char[sizeNeeded + 1]);

    // Doesn't return the whole field, only what was left...
    SQLGetData(_statement, _columnIndex, SQL_C_CHAR, (SQLCHAR*)largeBuffer.get(), sizeNeeded, &sizeNeeded);
}

Спасибо за любую помощь!

Ответы [ 2 ]

2 голосов
/ 28 февраля 2012

Ответственность за объединение данных лежит на вызывающем абоненте;ограничение на возврат данных в блоках может быть связано с поставщиком базы данных, а не с вашим кодом, поэтому вы должны иметь возможность обрабатывать случай в любом случае.

Также у вашего кода есть логический недостаток - вы можетеприходится вызывать SQLGetData несколько раз;каждый раз может возвращать дополнительные порции данных с SQL_SUCCESS_WITH_INFO / 01004, которые необходимо добавить в цикл.

0 голосов
/ 28 февраля 2012

Если вы заинтересованы в «сбросе» буфера выборки, я считаю, что позиция в столбце сохраняется только в том случае, если имя / индекс столбца одинаковы для двух последовательных вызовов. Другими словами, вызов SQLFetchData с другим именем столбца должен сбросить позицию в исходном столбце. Вот фрагмент от MSDN :

Последовательные вызовы SQLGetData будут извлекать данные из последнего запрошенного столбца; предыдущие смещения становятся недействительными. Например, когда выполняется следующая последовательность:

    SQLGetData(icol=n), SQLGetData(icol=m), SQLGetData(icol=n)

второй вызов SQLGetData (icol = n) извлекает данные из начала столбца n. Любое смещение в данных из-за более ранних вызовов SQLGetData для столбца больше недопустимо.

У меня нет под рукой спецификации ODBC, но MSDN, похоже, указывает на то, что это ожидаемое поведение. Лично я всегда накапливал результат нескольких вызовов непосредственно в строку, используя буфер фиксированного размера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...