Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.228.78] |
|
Страницы: (8) 1 [2] 3 4 ... 7 8 все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
структура infCol на каждый столбик возращает его размер infCol[i].len
Добавлено Пока вышел из положения так переставил dataRes = new char*[N50]; // Делаем динамический буфер for (int i = 0; i < pCol; ++i) // dataRes[i] = new char[infCol[i].len]; // выделяем памяти по размеру столбика из конструктора сразу после if (err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * SIZE_HCSQLDSTINFOT, &hcntOp) != 0) return err;// Получить информацию об операторе работает Добавлено но не правильно |
Сообщ.
#17
,
|
|
|
Я с базами почти не работал, но есть подозрение, что строка - это сумма всех колонок. Т.е. надо как-то так:
dataRes = new char*[N50]; // Делаем динамический буфер int totalLen=0; // общая длина for( int i = 0; i < pCol; i++) totalLen += infCol[i].len; // узнаём сумму for( int i = 0; i < N50; i++) // память для каждой из 50 строк dataRes[i] = new char[ totalLen ]; // выделяем Цитата kms @ Не совсем: просто появляется возможность вне класса лезть в класс и там менять данные, а это обычно не приветствуется. если так можно сделать чем это грозит , главное чтобы работало , или в смысле есть восможность что память выскочит или какой другой процесс поимеет доступ , в этом плане да ? Добавлено А ещё лучше (правильнее?) пробежаться по этим колонкам и узнать длину строки под числа, кои будут вписываться в строку. База же хранит всё в двоичном виде или как? int totalLen=0; // общая длина for( int j = 0; j < pCol; j++) switch( infCol[j].type )// в зависимости от типа { case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины totalLen += infCol[j].len; break; case HSCLI_ET_BYTE: // 2 Элемент - unsigned char (короткое целое) short totalLen += 3+1; break; // "123" + ноль на конце. ... } Ну что-то, быть может, в таком стиле. |
Сообщ.
#18
,
|
|
|
У них в библиотеке явно просматриваются как минимум две сущности -
/* Идентификатор соединения */ typedef int hcHDB; /* Идентификатор оператора */ typedef int hcHSTMT; Поэтому для начала нужно сделать соответствующие классы. Примерно вот так (очень приблизительный вариант, лень разбираться) namespace HiTech { class CConnection; class CStatement; class CConnection { public: CConnection() { const auto err = hcSqlAllocConnect(&m_db); if (err != 0) throw std::runtime_error("hcSqlAllocConnect failed"); } ~CConnection() { Disconnect(); hcSqlFreeConnect(m_db); } void Connect(const char *server, const char *user, const char *password) { const auto err = hcSqlConnect(m_db, server, user, password); if (err != 0) throw std::runtime_error("hcSqlConnect failed"); } void Disconnect() noexcept { hcSqlDisconnect(m_db); } //GetConnectAttr //SetConnectAtt //....... operator hcDB() const { return m_db; } protected: hcDB m_db; }; class CStatement { public: CStatement(CConnection &cnn) : m_cols(0) { auto err = hcSqlAllocStmt(cnn, &m_stmt); if (err != 0) throw std::runtime_error("hcSqlAllocStmt failed"); } ~CStatement() { hcSqlFreeStmt(m_stmt); } //SetStmtAtt void ExecDirect(const char *qry) { auto err = hcSqlExecDirect(cnn, &m_stmt); if (err != 0) throw std::runtime_error("hcSqlExecDirect failed"); m_cols = 0; m_spCols.reset(); int cols = 0; err = hcSqlNumResultCols(m_stmt, &cols); if (err != 0) throw std::runtime_error("hcSqlNumResultCols failed"); if (cols != 0) { std::unique_ptr<cSqlDstInfoT[]> spCols(new cSqlDstInfoT[cols]); size_t n = 0; err = hcSqlGetStmtAttr(m_stmt, HSCLI_STMT_DST_INFO, 0, spCols.get(), cols * sizeof(cSqlDstInfoT), &n); if (err = 0 || n != (cols * sizeof(cSqlDstInfoT))) throw std::runtime_error("hcSqlGetStmtAttr failed"); m_spCols = std::move(spCols); m_cols = cols; } } ////И т.д.......................... protected: hcHSTMT m_stmt; size_t m_cols; std::unique_ptr<cSqlDstInfoT[]> m_spCols; }; } |
Сообщ.
#19
,
|
|
|
Цитата Славян @ Я с базами почти не работал, но есть подозрение, что строка - это сумма всех колонок. Т.е. надо как-то так: dataRes = new char*[N50]; // Делаем динамический буфер int totalLen=0; // общая длина for( int i = 0; i < pCol; i++) totalLen += infCol[i].len; // узнаём сумму for( int i = 0; i < N50; i++) // память для каждой из 50 строк dataRes[i] = new char[ totalLen ]; // выделяем тут такой момент unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" hcSqlOpenResults ( pOper, &pRecSize ). получает размер строки в байтах это и есть как раз сумма всех полей поэтому высчитывать не надо она уже известна pRecSize тогда у вас тут точно не то dataRes = new char*[N50]; // Делаем динамический буфер int totalLen=0; // общая длина for( int i = 0; i < pCol; i++) totalLen += infCol[i].len; // узнаём сумму for( int i = 0; i < N50; i++) // память для каждой из 50 строк dataRes[i] = new char[ totalLen ]; // выделяем Добавлено Цитата Славян @ А ещё лучше (правильнее?) пробежаться по этим колонкам и узнать длину строки под числа, кои будут вписываться в строку. База же хранит всё в двоичном виде или как? int totalLen=0; // общая длина for( int j = 0; j < pCol; j++) switch( infCol[j].type )// в зависимости от типа { case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины totalLen += infCol[j].len; break; case HSCLI_ET_BYTE: // 2 Элемент - unsigned char (короткое целое) short totalLen += 3+1; break; // "123" + ноль на конце. ... } Ну что-то, быть может, в таком стиле. так то оно так только вот и не могу разобраться Добавлено Цитата Олег М @ У них в библиотеке явно просматриваются как минимум две сущности - /* Идентификатор соединения */ typedef int hcHDB; /* Идентификатор оператора */ typedef int hcHSTMT; Поэтому для начала нужно сделать соответствующие классы. ОК , я понял , пошел долбить и грызть Добавлено Да и еще самое главное ребята подскажите как же мне всетаки из класса выводить полученный результат я сейчас буду раскидывать на два класса как подсказал Олег М |
Сообщ.
#20
,
|
|
|
Ну можете хранить получаемое в классе, а для запроса такой то строки сделать некую GetStr:
class HyTech { ... int GetStr( int nomer); ... }; int HyTech::GetStr( char *str, int nomer) { strncpy( str, dataRes[nomer], n); } Добавлено Или даже как-то так (если данные выдаются в виде двоичных): int HyTech::GetStr( char *str, int nomer) { str[0] = 0; char *p=dataRes[nomer], num[20]; for( int j=0; j<pCol; j++) switch( infCol[j].type )// в зависимости от типа { case HSCLI_ET_BYTE: // 2 Элемент - unsigned char (короткое целое) short itoa( (int)p[0], num, 10 ); strcat( str, num); p++; break; // "123" + ноль на конце. ... } ... } |
Сообщ.
#21
,
|
|
|
Славян ОК буду пробовать , попозже отпишу результат
|
Сообщ.
#22
,
|
|
|
Олег М подскажи как вот это правильно применить
operator hcDB() const { return m_db; } я раскидал два класса на 4 файла, а эта перегрузка не пойму как ее применить |
Сообщ.
#23
,
|
|
|
Смотри конструктор, CStatement, она там уже применяется
|
Сообщ.
#24
,
|
|
|
Цитата Олег М @ namespace HiTech { class CConnection; class CStatement; class CConnection { public: CConnection() { const auto err = hcSqlAllocConnect(&m_db); if (err != 0) throw std::runtime_error("hcSqlAllocConnect failed"); } ~CConnection() { Disconnect(); hcSqlFreeConnect(m_db); } void Connect(const char *server, const char *user, const char *password) { const auto err = hcSqlConnect(m_db, server, user, password); if (err != 0) throw std::runtime_error("hcSqlConnect failed"); } void Disconnect() noexcept { hcSqlDisconnect(m_db); } //GetConnectAttr //SetConnectAtt //....... operator hcDB() const { return m_db; } protected: hcDB m_db; }; в смысле вот это ? но у меня ошибку дает , не хочет брать вообще вот это участок просто весь красный operator hcDB() const { return m_db; } protected: hcDB m_db; |
Сообщ.
#25
,
|
|
|
Цитата Олег М @ Смотри конструктор, CStatement, она там уже применяется в operator int() const { return pdb; } protected: int pdb = 0; Добавлено сделал так файл Statement.h #ifndef STATEMENT_H #define STATEMENT_H #include "HyTech.h" namespace HyTech { class CStatement { public: CStatement(CConnection & pdb); ~CStatement(); void ExecDirect(const char *qry); protected: hcHSTMT hstmt ; size_t Cols; std::unique_ptr<hcSqlDstInfoT[]> pCols; }; } #endif Statement.cpp #define HYCFG_WIN32 #include "HyTech.h" namespace HyTech { CStatement::CStatement(CConnection & pdb) { int err = hcSqlAllocStmt(pdb, &hstmt); } CStatement::~CStatement() { hcSqlFreeStmt(hstmt); } //SetStmtAtt void CStatement::ExecDirect(const char *qry) { auto err = hcSqlExecDirect(hstmt, qry); if (err != 0) throw std::runtime_error("hcSqlExecDirect failed"); Cols = 0; pCols.reset(); int col = 0; err = hcSqlNumResultCols(hstmt, &col); if (err != 0) throw std::runtime_error("hcSqlNumResultCols failed"); if (col != 0) { std::unique_ptr<hcSqlDstInfoT[]> pCols(new hcSqlDstInfoT[col]); size_t n = 0; err = hcSqlGetStmtAttr(hstmt, HSCLI_STMT_DST_INFO, 0, pCols.get(), col * sizeof(hcSqlDstInfoT), &n); if (err = 0 || n != (col * sizeof(hcSqlDstInfoT))) throw std::runtime_error("hcSqlGetStmtAttr failed"); pCols = std::move(pCols); Cols = col; } } ////И т.д.......................... } показывает ошибки ОшибкаC2061синтаксическая ошибка: идентификатор "CConnection" HyTech \desktop\hytech\hytech\statement.h12 ОшибкаC2061синтаксическая ошибка: идентификатор "CConnection" HyTech \desktop\hytech\hytech\statement.h12 ОшибкаC2511HiTech::CStatement::CStatement(HiTech::CConnection &): перегруженная функция-член не найдена в "HiTech::CStatement"HyTech \desktop\hytech\hytech\statement.cpp9 ОшибкаC2597недопустимая ссылка на нестатический член "HiTech::CStatement::hstmt"HyTech \desktop\hytech\hytech\statement.cpp10 ОшибкаC2664"hcERR hcSqlAllocStmt(hcHDB,hcHSTMT *)": невозможно преобразовать аргумент 2 из "hcHSTMT HiTech::CStatement::* " в "hcHSTMT *"HyTech \desktop\hytech\hytech\statement.cpp10 ОшибкаC2061синтаксическая ошибка: идентификатор "CConnection"HyTech \desktop\hytech\hytech\statement.h12 |
Сообщ.
#26
,
|
|
|
Цитата kms @ показывает ошибки В Statement.h сделай #include "Connection.h" Добавлено Цитата kms @ в смысле вот это ? но у меня ошибку дает , не хочет брать вообще вот это участок просто весь красный Что за ошибка? |
Сообщ.
#27
,
|
|
|
Цитата Олег М @ В Statement.h сделай #include "Connection.h" да это сделано через #include "HyTech.h" |
Сообщ.
#28
,
|
|
|
Покажи-ка все файлы
|
Сообщ.
#29
,
|
|
|
Цитата Олег М @ Что за ошибка? сейчас 6 ошибок на Statement.h и Statement.cpp ошибки см.Сообщ. #25 Добавлено Цитата Олег М @ Покажи-ка все файлы Connection.h #ifndef CONNECTION_H #define CONNECTION_H #include "HyTech.h" namespace HyTech { class CConnection { public: CConnection(); ~CConnection(); void Connect(const char *server, const char *user, const char *password); void Disconnect() noexcept; operator int() const { return pdb; } protected: int pdb = 0; // Адрес памяти, куда будет записан идентификатор соединения. hcHDB pdb; }; } #endif Connection.сpp #define HYCFG_WIN32 #include "HyTech.h" namespace HyTech { CConnection::CConnection() { const auto err = hcSqlAllocConnect(&pdb); if (err != 0) throw std::runtime_error("hcSqlAllocConnect failed"); } CConnection::~CConnection() { Disconnect(); hcSqlFreeConnect(pdb); } void CConnection::Connect(const char * server, const char * user, const char * password) { const auto err = hcSqlConnect(pdb, server, user, password); if (err != 0) throw std::runtime_error("hcSqlConnect failed"); } void CConnection::Disconnect() noexcept { hcSqlDisconnect(pdb); } } Statement.h #ifndef STATEMENT_H #define STATEMENT_H #include "HyTech.h" namespace HyTech { class CStatement { public: CStatement(CConnection & pdb); ~CStatement(); void ExecDirect(const char *qry); protected: hcHSTMT hstmt ; // Адрес памяти, куда будет записан идентификатор созданного оператора. size_t Cols; std::unique_ptr<hcSqlDstInfoT[]> pCols; }; } #endif Statement.cpp #define HYCFG_WIN32 #include "HyTech.h" namespace HyTech { CStatement::CStatement(CConnection & pdb) { int err = hcSqlAllocStmt(pdb, &hstmt); } CStatement::~CStatement() { hcSqlFreeStmt(hstmt); } //SetStmtAtt void CStatement::ExecDirect(const char *qry) { auto err = hcSqlExecDirect(hstmt, qry); if (err != 0) throw std::runtime_error("hcSqlExecDirect failed"); Cols = 0; pCols.reset(); int col = 0; err = hcSqlNumResultCols(hstmt, &col); if (err != 0) throw std::runtime_error("hcSqlNumResultCols failed"); if (col != 0) { std::unique_ptr<hcSqlDstInfoT[]> pCols(new hcSqlDstInfoT[col]); size_t n = 0; err = hcSqlGetStmtAttr(hstmt, HSCLI_STMT_DST_INFO, 0, pCols.get(), col * sizeof(hcSqlDstInfoT), &n); if (err = 0 || n != (col * sizeof(hcSqlDstInfoT))) throw std::runtime_error("hcSqlGetStmtAttr failed"); pCols = std::move(pCols); Cols = col; } } ////И т.д.......................... } |
Сообщ.
#30
,
|
|
|
Цитата kms @ #ifndef CONNECTION_H #define CONNECTION_H Вместо этого можно ставить просто #pragma once Добавлено Цитата kms @ Connection.сpp #define HYCFG_WIN32 #include "HyTech.h" Здесь надо #include "Connection.h" Добавлено Цитата kms @ operator int() const { return pdb; } Верни как у меня Добавлено Цитата kms @ Statement.h #ifndef STATEMENT_H #define STATEMENT_H #include "HyTech.h" Здесь тоже надо #include "Connection.h" |