Member 13872723 Ответов: 1

Чтение ODBC после окончания записи в access и excel


Теперь у меня есть код ODBC, который успешно открывает и считывает данные как из файлов Access, так и из файлов Excel.
Проблема в том, что в обоих случаях ODBC продолжает "читать" после конца записи, возвращая ненужные значения. В результате процесс зависает, и я не могу продвинуться дальше первой записи.
Любая помощь будет оценена по достоинству.

Что я уже пробовал:

Попробовал отладку в Visual Studio. Попробовал онлайн-справку.

Maciej Los

Какой у тебя код? Примечание: мы не можем читать непосредственно с вашей головы или экрана...

Member 13872723

Вот мой код:
// Республиканская база данных Analytics.cpp : определяет точку входа для консольного приложения.
//

код #include "файл stdafx.ч"

#включить <windows.h>
#include <sqlext.h>
#include <mbstring.h>
#включить <stdio.h>
#include <string>
#включить <вектор>

SQLRETURN GetResultset();



пустота DescribeColumns();
структура ColDescription
{
SQLSMALLINT colNumber;
SQLCHAR colName[80];
SQLSMALLINT nameLen;
Тип данных SQLSMALLINT;
SQLULEN colSize;
SQLSMALLINT decimalDigits;
Значение null SQLSMALLINT ;
};

использование пространства имен std;
std::vector <coldescription> cols;
StmtHandle аргумент sqlhandle ;
std::vector< std::vector<std::string> > colData;

RETCODE rc; // код возврата ODBC
Ул. SQLRETURN GetColData(инт colnum, стринги и усилитель; amp; )
{
SQLCHAR buf[255] = { 0 };
если ((функция sqlgetdata(StmtHandle, colnum, как типы данных sql_char, баф, оператор sizeof(buf с), значение null)) == значение sql_success)
str = reinterpret_cast<char*>(buf);
возвращение RC;
}


тап_п()
{
RETCODE rc; // код возврата ODBC
//ХЕНВ хенв;
//2HDBC hdbc; // ручка подключения

Аргумент sqlhandle EnvHandle;


rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &EnvHandle);
SQLHANDLE ConHandle = 0;

if (rc == SQL_SUCCESS)
{
rc = SQLSetEnvAttr(EnvHandle, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3, SQL_IS_UINTEGER);
}

rc = SQLAllocHandle(SQL_HANDLE_DBC, EnvHandle, &ConHandle);




//SQLAllocEnv(&henv);
//SQLAllocConnect(henv, &hdbc);
// std::wstring ds_name = L"ежедневная рабочая книга"; // имя источника данных
//unsigned char chr_ds_name[SQL_MAX_DSN_LENGTH]; // имя источника данных

// _mbscpy_s(chr_ds_name, SQL_MAX_DSN_LENGTH, (const unsigned char *)"ежедневная рабочая книга");

//rc = SQLConnect(hdbc, (SQLWCHAR*)("ежедневная рабочая книга"), SQL_NTS, NULL, 0, NULL, 0);


//strcpy((char *)SQLStmt, "SELECT * FROM categories");
unsigned char chr_ds_name[SQL_MAX_DSN_LENGTH]; // имя источника данных
//_mbscpy_s(chr_ds_name, SQL_MAX_DSN_LENGTH, (const unsigned char *)"dailyworkbook");



//SQLWCHAR dsn[] = L"dailyworkbook";
//РК = функция sqlconnect(ConHandle, уведомление о доставке, 3000, нуль, 0, нуль, 0);
std::wstring dsn(L"daily_excel");
РЦ = функция sqlconnect(ConHandle, const_cast&ЛТ;SQLWCHAR*&ГТ;(ДСН.c_str()), значение sql_nts, нуль, 0, нуль, 0);

SQLHSTMT hstmt;

SQLCHAR SqlState[6];
SQLINTEGER NativeError;
wchar_t Msg[SQL_MAX_MESSAGE_LENGTH];
SQLSMALLINT i, MsgLen;

wchar_t wpb[6];

//Функцию sqlgetdiagrec(SQL_HANDLE_DBC, ConHandle, 1, ДСП, &ампер;NativeError, глутамат натрия, оператор sizeof(глутамат натрия), &ампер;MsgLen);
rc = SQLAllocHandle(SQL_HANDLE_STMT, ConHandle, &StmtHandle);

//SQLCHAR SQLStmt[255] = { 0 };


// strcpy_s((char *)SQLStmt, "SELECT * FROM sheet1");

if (rc == SQL_SUCCESS)
{
wchar_t wob[] = L"SELECT * FROM [Sheet1$]";
РЦ = функцию sqlexecdirect(StmtHandle, нагрузка на долото, значение sql_nts);

if (rc == SQL_SUCCESS)
{
// GetResultset();
}
еще
{
Функцию sqlgetdiagrec(SQL_HANDLE_STMT, StmtHandle, 1, ДСП, &ампер;NativeError, глутамат натрия, оператор sizeof(глутамат натрия), &ампер;MsgLen);
}

if (rc == SQL_SUCCESS)
{
Описаниеколумны();
colData.понятно();

while (SQLFetch(StmtHandle) == SQL_SUCCESS)
{
std::vector<std::string> col;
СТД::строка данных;
int i = 1;


while (GetColData(i, data) == SQL_SUCCESS)
{
col.push_back(данные);
++i; // увеличить номер столбца

}

colData.push_back(кол.);
}
}
}



возвращает 0;
}

SQLRETURN Describe(ColDescription& c)
{
возвращение функции sqldescribecol(StmtHandle, гр.colNumber,
(SQLWCHAR*)Си.colName, оператор sizeof(ок. colName), и усилитель;с.nameLen,
&усилитель;с.типа, &усилитель;с.colSize, и усилитель;с.decimalDigits, и усилитель;с.допускающий значение null);
}


пустота DescribeColumns()
{
ColDescription с;
c.colNumber = 1;
седла.понятно();

while (Describe(c) == SQL_SUCCESS)
{
седла.push_back(с);
с++.colNumber;
}

}

Maciej Los

Используйте виджет "улучшить вопрос" (rigth-нижний угол) вместо кода postng в комментарии.

1 Ответов

Рейтинг:
0

Jochen Arndt

Ошибка, вероятно, находится в коде, опубликованном в качестве комментария:

RETCODE rc; // ODBC return code
SQLRETURN GetColData(int colnum, string& str)
{
    SQLCHAR buf[255] = { 0 };
    if ((SQLGetData(StmtHandle, colnum, SQL_CHAR, buf, sizeof(buf), NULL)) == SQL_SUCCESS)
        str = reinterpret_cast<char*>(buf);
    return rc;
}
Эта функция возвращает содержимое (неинициализированной) переменной gobal rc который никогда не изменяется внутри функции.

Когда глобальная переменная равна нулю, ваш цикл, вызывающий эту функцию, пока она возвращает SQL_SUCCESS, никогда не закончится.

Используйте локальную переменную, которой присваивается возвращаемое значение функции:
// Delete this to ensure that only local variables are used!
//RETCODE rc; // ODBC return code
SQLRETURN GetColData(int colnum, string& str)
{
    SQLCHAR buf[255] = { 0 };
    RETCODE rc = SQLGetData(StmtHandle, colnum, SQL_CHAR, buf, sizeof(buf), NULL);
    if (rc == SQL_SUCCESS)
        str = buf;
    return rc;
}
Там также не должно быть никакой необходимости бросать buf потому что SQLCHAR является char.