Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.189.170.17] |
|
Сообщ.
#1
,
|
|
|
Имеется DLL , описание функции из этой DLL
Скрытый текст hcSqlReadResults — Чтение результатов Назначение Чтение результатов Прототип hcERR hcSqlReadResults( hcHSTMT h, /* Оператор с результатами */ hcRECNO gStart, /* С какой записи начинаем читать */ void *pBuf, unsigned wBufSize, unsigned *cnt) /* Сколько прочитали */ Параметры: Тип Аргумент Значение hcHSTMT h Идентификатор оператора, содержащего результаты поиска оператором select. hcRECNO gStart Номер записи в результате, начиная с которой пересылаются результаты. Все найденные записи нумеруются с 0. void * pBuf Адрес буфера для присылаемых записей. unsigned wBufSize Размер буфера для результатов. В буфер помещается целое количество записей. Если запись не может войти в буфер целиком, она не присылается. unsigned * cnt Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. Результат Тип Результат Значение hcERR равно 0. Операция успешно выполнена. При достижении конца результатов функция также возвращает 0, но и количество считанных байтов данных в этом случает возвращается нулевым. Не равно 0 Код ошибки. Причем ошибка ввода/вывода может возникнуть как на сервере при чтении данных, так и при передаче между сервером и прикладной программой. файл .h к этой DLL Скрытый текст /*************************************************************** Интерфейс к динамической библиотеке HSCLI.DLL Клиент (1.1.6.16) История: ======== 22.10.04 Тестовый вариант ***************************************************************/ #ifndef HSCLI_H_INCLUDED #define HSCLI_H_INCLUDED /* Для построения фиктивной DLL*/ #ifdef HSCLI_DUMMY_DLL #define HSCLI_DLL #define HSCLI_EOF { return 0; } #else #define HSCLI_EOF ; #endif #ifdef __cplusplus # define HSCLI_PFX extern "C" #else # define HSCLI_PFX #endif /* Функции, экспортируемые из DLL */ #if defined(HYCFG_SOLARIS) || defined(HYCFG_LINUX) # define HSCLI_FUN(type) HSCLI_PFX type # define HSCLI_CBK #elif defined(HYCFG_NETWARE) # ifdef HSCLI_DLL # define HSCLI_FUN(type) HSCLI_PFX type _export # define HSCLI_CBK # else # define HSCLI_FUN(type) HSCLI_PFX type # define HSCLI_CBK # endif #elif defined(HYCFG_WIN32) # ifdef HSCLI_DLL # define HSCLI_FUN(type) HSCLI_PFX type __declspec(dllexport) __stdcall # define HSCLI_CBK __stdcall # else # define HSCLI_FUN(type) HSCLI_PFX type __declspec(dllimport) __stdcall # define HSCLI_CBK __stdcall # endif #else # error !os #endif /* Ошибки локальной части */ #define SQL_RTL_LCL_REMOTE -20001 /* Ошибка связи */ #define SQL_RTL_LCL_USER_BREAK -20002 /* Обработка прервана пользователем */ #define SQL_RTL_LCL_NO_INIT -20003 /* Не инициализировано */ #define SQL_RTL_LCL_GENERAL_ERROR -20004 /* Другая ошибка */ #define SQL_RTL_LCL_BUSY -20005 /* Предыдущая операция не завершена */ #define SQL_RTL_LCL_NO_MEMORY -20006 /* Мало памяти */ #define SQL_RTL_LCL_TOO_MANY_SESSIONS -20007 /* Много сессий */ #define SQL_RTL_LCL_INV_ARG -20008 /* Неправильный аргумент */ #define SQL_RTL_LCL_TOO_OLD_SERVER -20009 /* Старый сервер */ /*************************************************************** Типы данных и константы ***************************************************************/ /* Идентификатор оператора */ typedef int hcHSTMT; /* Идентификатор соединения */ typedef int hcHDB; /* Номер поля */ typedef int hcFLD; /* Номер записи в таблице или результате */ typedef long hcRECNO; /* Обработчик записи */ typedef long hcRHANDLE; /* Код ошибки */ //#ifndef HSCLI_DLL typedef int hcERR; //#endif /* Функция обработки текстовых сообщений сервера */ typedef void HSCLI_CBK hcSqlCbkSrvMsgT(hcHDB conn, int is_err); typedef void HSCLI_CBK hcSqlCbkStmtSrvMsgT(hcHDB conn, hcHSTMT stmt, int is_err); /* Функция обработки Usersend */ typedef void HSCLI_CBK hcSqlCbkSrvUserSendT(hcHDB conn, int usertype); typedef void HSCLI_CBK hcSqlCbkStmtSrvUserSendT(hcHDB conn, hcHSTMT stmt, int usertype); /* Параметры инициализации */ typedef struct hcSqlParmT { unsigned size; /* Размер структуры */ } hcSqlParmT; /*************************************************************** Функции ***************************************************************/ /* Инициализировать клиентскую часть */ HSCLI_FUN(hcERR) hcSqlInit( hcSqlParmT *arg) /* Аргументы инициализации */ HSCLI_EOF /* Завершить работу */ HSCLI_FUN(hcERR) hcSqlDone(void) HSCLI_EOF /* Проверить завершение инициализации */ HSCLI_FUN(hcERR) hcSqlCheckInit(void) HSCLI_EOF /* Создать соединение */ HSCLI_FUN(hcERR) hcSqlAllocConnect( hcHDB *pdb) /* Соединение */ HSCLI_EOF /* Освободить соединение */ HSCLI_FUN(hcERR) hcSqlFreeConnect( hcHDB hdb) /* Соединение */ HSCLI_EOF /* Установить связь с сервером БД */ HSCLI_FUN(hcERR) hcSqlConnect( hcHDB hdb, /* Идентификатор соединения */ const char *server, const char *user, const char *password) HSCLI_EOF /* Разорвать связь с сервером БД */ HSCLI_FUN(hcERR) hcSqlDisconnect( hcHDB hdb) /* Идентификатор соединения */ HSCLI_EOF /* Получить информацию об соединении */ #define HSCLI_CONN_SRV_PATH 101 /* строка соединения (char[]) */ #define HSCLI_CONN_SRV_VERS 102 /* Версия сервера (double) */ #define HSCLI_CONN_SRV_VERS2 103 /* Версия сервера (char[]) */ #define HSCLI_CONN_USER_INFO 151 /* Информация пользователя (long) */ #define HSCLI_CONN_LCLADDR 152 /* Адрес (клиента) (char[]) */ #define HSCLI_CONN_RMTADDR 153 /* Адрес (сервера) (char[]) */ HSCLI_FUN(hcERR) hcSqlGetConnectAttr( hcHDB h, /* Идентификатор соединения */ unsigned option, /* Режим */ int pos, /* Позиция */ void *pValue, /* Буфер для значения */ unsigned size, /* и его размер */ unsigned *cnt) /* сколько байтов записали в буфер */ HSCLI_EOF #define HSCLI_ATTR_FLD_VERBOSE 1001 /* [conn/stmt] Расширенная информация о полях (int) */ #define HSCLI_ATTR_CONN_USER_INFO 1002 /* [conn/stmt] Информация пользователя (long) */ #define HSCLI_ATTR_CBK_SRVMSG 1100 /* [conn] Функция обработки сообщений сервера (hcSqlCbkSrvMsgT*) */ #define HSCLI_ATTR_CBK_SRVUSERSEND 1101 /* [conn] Функция обработки пользовательских сообщений сервера (hcSqlCbkSrvUserSendT*) */ #define HSCLI_ATTR_CBK_STMT_SRVMSG 1102 /* [stmt] Функция обработки сообщений сервера (hcSqlCbkStmtSrvMsgT*) */ #define HSCLI_ATTR_CBK_STMT_SRVUSERSEND 1103 /* [stmt] Функция обработки пользовательских сообщений сервера (hcSqlCbkStmtSrvUserSendT*) */ /* Изменение параметров соединения */ HSCLI_FUN(hcERR) hcSqlSetConnectAttr( hcHDB h, /* Идентификатор соединения */ unsigned option, /* Режим */ void *pValue, /* Значение (int/long) или буфер значения */ unsigned size) /* Размер значения в байтах или 0, если передаётся int/long */ HSCLI_EOF /* Сменить пароль пользователя * Результат: = 0 - успех, < 0 - ошибка */ HSCLI_FUN(hcERR) hcSqlAlterPassword( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя пользователя */ const char *oldpswd, /* Старый пароль */ const char *newpswd) /* Новый пароль */ HSCLI_EOF /* Создать пользователя * Результат: = 0 - успех, < 0 - ошибка */ HSCLI_FUN(hcERR) hcSqlCreateUser( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя пользователя */ const char *pswd, /* Пароль */ const char *profile, /* Профиль */ const char *startup) /* Стартовый файл */ HSCLI_EOF /* Создать Источник данных * Результат: = 0 - успех, < 0 - ошибка */ HSCLI_FUN(hcERR) hcSqlCreateDatasrc( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя источника */ const char *driver, /* Имя драйвера */ const char *user, /* имя пользователя */ const char *pswd) /* Пароль */ HSCLI_EOF /* Смена логина у источника данных * Результат: = 0 - успех, < 0 - ошибка */ HSCLI_FUN(hcERR) hcSqlAlterDatasrcLogin( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя источника */ const char *user, /* имя пользователя */ const char *pswd) /* Пароль */ HSCLI_EOF /* Создать оператор */ HSCLI_FUN(hcERR) hcSqlAllocStmt( hcHDB db, /* Соединение */ hcHSTMT *p) /* Место для номера оператора */ HSCLI_EOF /* Закрыть оператор */ HSCLI_FUN(hcERR) hcSqlFreeStmt( hcHSTMT h) /* Идентификатор оператора */ HSCLI_EOF /* Изменение параметров оператора */ HSCLI_FUN(hcERR) hcSqlSetStmtAttr( hcHSTMT h, /* Идентификатор оператора */ unsigned option, /* Режим */ void *pValue, /* Значение (int/long) или буфер значения */ unsigned size) /* Размер буфера или 0, если передаётся int/long */ HSCLI_EOF /* Странслировать и выполнить SQL-скрипт */ HSCLI_FUN(hcERR) hcSqlExecDirect( hcHSTMT h, /* Идентификатор оператора */ const char *text) /* Текст SQL-скрипта */ HSCLI_EOF /* Странслировать и выполнить SQL-скрипт */ HSCLI_FUN(hcERR) hcSqlExecDirectAsync( hcHSTMT h, /* Идентификатор оператора */ const char *text) /* Текст SQL-скрипта */ HSCLI_EOF /* Получить результат выполнения запроса */ HSCLI_FUN(hcERR) hcSqlExecDirectQuery( hcHSTMT h) /* Идентификатор оператора */ HSCLI_EOF /* Получить количество колонок результата */ HSCLI_FUN(hcERR) hcSqlNumResultCols( hcHSTMT h, /* Идентификатор оператора */ int *pCol) /* Место для количества колонок */ HSCLI_EOF /* Получить количество строк результата */ HSCLI_FUN(hcERR) hcSqlRowCount( hcHSTMT h, /* Идентификатор оператора */ hcRECNO *pCnt) /* Место для количества строк */ HSCLI_EOF /* Тип результата в операторе */ #define HSCLI_RES_NONE -1 /* Результата нет */ #define HSCLI_RES_RECORD 0 /* Результат содержит список записей */ #define HSCLI_RES_JOIN 3 /* Результат содержит результат слияния таблиц */ #define HSCLI_RES_SORTED 4 /* Результат содержит отсортированный список записей */ #define HSCLI_RES_GROUP 5 /* Результат содержит результаты операции группировки */ #define HSCLI_RES_SORTJOIN 6 /* Результат содержит отсортированное слияние таблиц */ /* Базовые типы данных в БД */ #define HSCLI_ET_CHAR 0 /* Массив символов длиной не более заданной */ #define HSCLI_ET_ARRA 1 /* Массив байтов заданной длины */ #define HSCLI_ET_BYTE 2 /* Элемент - unsigned char (короткое целое) */ #define HSCLI_ET_INTR 3 /* Элемент - signed short */ #define HSCLI_ET_WORD 4 /* Элемент - unsigned short */ #define HSCLI_ET_DATE 5 /* Дата - unsigned short */ #define HSCLI_ET_NMBR 6 /* Номер - 3-х байтовое целое без знака */ #define HSCLI_ET_LONG 7 /* Элемент - long int */ #define HSCLI_ET_DWRD 8 /* Элемент - unsigned long int */ #define HSCLI_ET_FLOA 9 /* Элемент - float */ #define HSCLI_ET_CURR 10 /* Деньги (double) */ #define HSCLI_ET_DFLT 11 /* Элемент - double */ #define HSCLI_ET_QINT 12 /* Элемент - signed __int64 */ #define HSCLI_ET_QWRD 13 /* Элемент - unsigned __int64 */ /* Ключевые поля в БД */ #define HSCLI_EK_NOTKEY 0 /* Элемент не ключ */ #define HSCLI_EK_COMMON 1 /* Обычный ключ */ #define HSCLI_EK_UNIQUE 2 /* Уникальный ключ */ #define HSCLI_EK_SURRGT 3 /* Суррогатный ключ */ /* Получить информацию об операторе */ #define HSCLI_STMT_SAB_TYPE 102 /* тип результата в SAB (int) */ #define HSCLI_STMT_SAB_HNDCNT 103 /* количество ht-обработчиков (int) */ #define HSCLI_STMT_SAB_HANDLES 104 /* ht-обработчики (int * i) */ #define HSCLI_STMT_ALS_CNT 105 /* количество alias-ов (int) */ typedef struct hcSqlAliasInfoT { int hthandle; char tname[32]; char aname[32]; } hcSqlAliasInfoT; #define HSCLI_STMT_ALS_INFO 106 /* информация об алиасах (aliasinfo * i) */ typedef struct hcSqlDstInfoT { int aliasno; int fieldno; int type; unsigned len; unsigned off; char coder[32]; char fname[32]; int func; char asname[32]; int key; int resno; } hcSqlDstInfoT; #define HSCLI_STMT_DST_INFO 107 /* Информация об колонке результата dst (dstinfo * i) */ #define HSCLI_STMT_RC_TYPE 109 /* Тип retcode (int) */ #define HSCLI_STMT_RC_SIZE 110 /* Длина retcode (int) */ #define HSCLI_STMT_RC_BODY 111 /* Значение retcode (char[], long, double) */ #define HSCLI_STMT_CURSNO 140 /* Номер курсора в HTSQL-сервере (int) */ HSCLI_FUN(hcERR) hcSqlGetStmtAttr( hcHSTMT h, /* Идентификатор оператора */ unsigned option, /* Режим */ int pos, /* Позиция */ void *pValue, /* Буфер для значения */ unsigned size, /* и его размер */ unsigned *cnt) /* сколько байтов записали в буфер */ HSCLI_EOF /* Открыть результаты для чтения. Читаются данные, отобранные * оператором select с учетом тех выражений, которые в нем заданы. */ HSCLI_FUN(hcERR) hcSqlOpenResults( hcHSTMT h, /* Оператор с результатами */ unsigned *pRecSize) /* Сюда запишется размер записи */ HSCLI_EOF /* Чтение результатов с указанной позиции */ HSCLI_FUN(hcERR) hcSqlReadResults( hcHSTMT h, /* Оператор с результатами */ hcRECNO gStart, /* С какой записи начинаем читать */ void *pBuf, /* Адрес буфера для результатов */ unsigned wBufSize, /* Размер буфера этого буфера */ unsigned *cnt) /* Сколько прочитали */ HSCLI_EOF /* Закрыть доступ к результатам */ HSCLI_FUN(hcERR) hcSqlCloseResults( hcHSTMT h) /* Оператор с результатами */ HSCLI_EOF /*************************************************************** "Странные" функции ***************************************************************/ /* Добавить элемент в результаты поиска * Доступ к исходным результатам должен быть открыт */ HSCLI_FUN(hcERR) hcSqlIncludeResultsItem( hcHSTMT h, /* Оператор с результатами */ hcRECNO gRecNo, /* Куда вставлять (от 0) */ /* RES_RECORD - физ.номер записи */ const void *pNewItem, /* Новый элемент результата: */ /* RES_SORTED - обработчик записи */ /* RES_JOIN - группа обработчиков записей для таблиц слияния */ /* RES_VALUE, RES_HISTO, RES_GROUP - тело элемента */ unsigned wLen) /* Длина нового элемента (в байтах) */ HSCLI_EOF /* Исключить элемент из результатов поиска * Доступ к исходным результатам должен быть открыт */ HSCLI_FUN(hcERR) hcSqlExcludeResultsItem( hcHSTMT h, /* Оператор с результатами */ hcRECNO gRecNo) /* Что удалять (от 0) */ /* RES_RECORD - физ.номер записи */ HSCLI_EOF /* Заменить элемент в результатах поиска * Доступ к исходным результатам должен быть открыт */ HSCLI_FUN(hcERR) hcSqlReplaceResultsItem( hcHSTMT h, /* Оператор с результатами */ hcRECNO gRecNo, /* Что менять (от 0) */ /* RES_RECORD - физ.номер записи */ const void *pNewItem, /* Новый элемент результата: */ /* RES_SORTED - обработчик записи */ /* RES_JOIN - группа обработчиков записей для таблиц слияния */ /* RES_VALUE, RES_HISTO, RES_GROUP - тело элемента */ unsigned wLen) /* Длина нового элемента (в байтах) */ HSCLI_EOF /* Считать элемент результата поиска - обработчик записи(ей) * Доступ к исходным результатам должен быть открыт * Допустим для результатов RES_RECORD, RES_SORTED и RES_JOIN */ /* Аналог функции htGetResultsItem */ HSCLI_FUN(hcERR) hcSqlGetResultsItem( hcHSTMT h, /* Оператор с результатами */ hcRECNO gRecNo, /* Что читать (от 0) */ /* RES_RECORD - физ.номер записи */ void *pItem, /* Длина элемента определяется типом результата: */ /* RES_SORTED - sizeof(RHANDLE) */ /* RES_JOIN - sizeof(RHANDLE) * число_таблиц_слияния */ unsigned bufsz) /* Длина буфера для чтения */ HSCLI_EOF /* "Освежить" результаты поиска (несортированные записи), привести */ /* их в соответствие с текущим состоянием таблицы. */ /* Доступ к исходным результатам должен быть закрыт */ HSCLI_FUN(hcERR) hcSqlStmtTouch( hcHSTMT h) /* Оператор с результатами */ HSCLI_EOF /* Удаление найденных записей из таблицы */ HSCLI_FUN(hcERR) hcSqlStmtDeleteResults( hcHSTMT h, /* Оператор с результатами */ long *cnt) /* Количество удалённых записей */ HSCLI_EOF /* Сортировка результатов в курсоре */ HSCLI_FUN(hcERR) hcSqlStmtSort( hcHSTMT h, /* Оператор с результатами */ int nFldCnt, /* Количество полей для сортировки */ hcFLD *pFields) /* Номера полей для сортировки */ HSCLI_EOF /* Определить подмножество записей таблицы, попавших в сортировку */ HSCLI_FUN(hcERR) hcSqlStmtUnsort( hcHSTMT h) /* Оператор с результатами */ HSCLI_EOF /*************************************************************** "Очень странные" функции ***************************************************************/ /* Добавление записи */ HSCLI_FUN(hcERR) hcSqlInsertRecord( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя таблицы */ unsigned len, /* Длина записи */ void *pRecord, /* Тело записи */ hcRECNO *pRecNo) /* Сюда запишется номер записи */ HSCLI_EOF /* Пакетное добавление */ HSCLI_FUN(hcERR) hcSqlAddRecords( hcHDB hdb, /* Идентификатор соединения */ const char *pName, /* Краткое имя таблицы */ hcRECNO gRecCount, /* Количество записей */ unsigned wRecSize, /* Размер записи */ const void *pBuf) /* Адрес буфера с телами записей */ HSCLI_EOF /* Получить запись с номером по обработчику */ HSCLI_FUN(hcERR) hcSqlReadRecordByHandle( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя таблицы */ hcRHANDLE hRecord, /* Обработчик записи */ void *pRecord, /* Адрес буфера для записи с номером */ unsigned bufsz) /* Размер буфера */ HSCLI_EOF /* Получить обработчик записи по физическому номеру */ HSCLI_FUN(hcERR) hcSqlHandleFromRecNo( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя таблицы */ hcRECNO gRecNo, /* Номер записи */ hcRHANDLE *record) HSCLI_EOF /* Модификация курсора */ #define HSCLI_OP_POSITION 1 /* Позиционирование и чтение */ #define HSCLI_OP_REFRESH 2 /* Чтение свежей записи */ #define HSCLI_OP_UPDATE 3 /* Модификация */ #define HSCLI_OP_DELETE 4 /* Удаление */ #define HSCLI_OP_INSERT 5 /* Вставка */ #define HSCLI_LOCK_BEFORE 0x0001 /* Захват записи перед операцией */ #define HSCLI_UNLOCK_AFTER 0x0002 /* Освобождение записи после операции */ #define HSCLI_LOCK_INTIME 0x0004 /* Захват записи во время операции */ #define HSCLI_RECORD_MAIN 0x0008 /* Захват только главной записи */ #define HSCLI_TWISE_ERROR 0x0010 /* Двойной захват - ошибка */ HSCLI_FUN(hcERR) hcSqlStmtEdit( hcHSTMT h, /* Оператор с результатами */ const char *pTab, /* Имя псевдонима таблицы в запросе или 0 */ hcRECNO row, /* Номер строки в курсоре (считается от 0) */ int op, /* Операция: HSSQL_OP_??? */ int lock, /* Захват, битовая маска, HS_LOCK/HS_UNLOCK */ void *buf, /* Адрес буфер записи */ unsigned sz, /* Размер буфера */ hcRECNO *recno) HSCLI_EOF /* Вставить в курсор несколько записей с указанными номерами */ HSCLI_FUN(hcERR) hcSqlFormRecordsSet( hcHSTMT h, /* Оператор с результатами */ const char *pName, /* Короткое имя таблицы, по которой надо создать курсор, или NULL */ hcRECNO gCnt, /* Количество вставляемых записей */ const hcRECNO *pRecordNo) /* Адрес массива с номерами записей */ HSCLI_EOF /* Чтение данных сообщения */ HSCLI_FUN(hcERR) hcSqlConnReadMsg( hcHDB hdb, /* Идентификатор соединения */ void *buf, /* Адрес буфер записи */ unsigned sz, /* Размер буфера */ unsigned *cnt) /* Сколько прочитали */ HSCLI_EOF /*************************************************************** Внутреннее представление данных ***************************************************************/ /* Упаковка даты */ /* 0 - неправильная дата */ HSCLI_FUN(unsigned short) hcSqlPackDate( unsigned day, /* День месяца (1-31) */ unsigned month, /* Месяц (1-12) */ unsigned year) /* Год (1900-2078) */ HSCLI_EOF /* Распаковка даты */ HSCLI_FUN(hcERR) hcSqlUnpackDate( unsigned short htdate, unsigned *day, unsigned *month, unsigned *year) HSCLI_EOF /* Выделение строки из поля, возвращается флаг потери информации */ HSCLI_FUN(int) hcSqlGetChar( char *dst, /* Буфер строки (с \0 символом в конце) */ unsigned dstlen, /* Длина буфера строки */ const unsigned char *field, /* Поле */ unsigned fldlen) /* Длина поля */ HSCLI_EOF /* Определение длины строки в поле */ HSCLI_FUN(unsigned) hcSqlGetCharLen( const unsigned char *field, /* Поле */ unsigned fldlen) /* Длина поля */ HSCLI_EOF /* Занесение строки в поле, возвращается флаг потери информации */ HSCLI_FUN(int) hcSqlSetChar( unsigned char *field, /* Поле */ unsigned fldlen, /* Длина поля */ const char *src) /* Исходная строка */ HSCLI_EOF /* Занесение null-значения */ HSCLI_FUN(hcERR) hcSqlSetNull( unsigned char *field, /* Поле */ int type, /* Тип поля (HSCLI_ET_???) */ unsigned typlen) /* Длина поля переменной длины */ HSCLI_EOF /* Проверка null-значения */ HSCLI_FUN(hcERR) hcSqlIsNull( const unsigned char *field, /* Поле */ int type, /* Тип поля (HSCLI_ET_???) */ unsigned typlen) /* Длина поля переменной длины */ HSCLI_EOF HSCLI_FUN(hcERR) hscliProcStart(void); HSCLI_FUN(hcERR) hscliProcExit(void); HSCLI_FUN(hcERR) hscliThrdStart(void); HSCLI_FUN(hcERR) hscliThrdExit(void); #endif пытаюсь исполнить вот так Скрытый текст // - - - - - - - - - - - - - - - --------------------------- Чтение результатов ----------------- hcRECNO gStart ; // С какой записи начинаем читать void *pBuf ; //Адрес буфера для присылаемых записей unsigned wBufSize ; // Размер буфера для результатов. unsigned *pCnt , hCnt ; // Сколько прочитали pCnt =&hCnt; cout << "\nФ-я hcSqlReadResults= " << hcSqlReadResults( hOper, gStart, &pBuf, wBufSize, pCnt); //---------------------------------------------------------------------------------------------------- Подскажите где у меня ошибка |
Сообщ.
#2
,
|
|
|
Ты передаёшь туда адрес указателя на void, &pBuf. И мусор в wBufSize. И cnt тоже неправильно
А надо, наверное, что-то типа char buf[1024] unsigned cnt = 0; hcSqlReadResults( hOper, gStart, buf, sizeof(buf), &cnt); Добавлено А ты вообще эти переменным присваиваешь какие-нибудь значения перед вызовом? Или так и вызываешь? |
Сообщ.
#3
,
|
|
|
Цитата kms @ Имеется DLL , описание функции из этой DLL Скрытый текст hcSqlReadResults — Чтение результатов Назначение Чтение результатов Прототип hcERR hcSqlReadResults( hcHSTMT h, /* Оператор с результатами */ hcRECNO gStart, /* С какой записи начинаем читать */ void *pBuf, unsigned wBufSize, unsigned *cnt) /* Сколько прочитали */ Параметры: Тип Аргумент Значение hcHSTMT h Идентификатор оператора, содержащего результаты поиска оператором select. hcRECNO gStart Номер записи в результате, начиная с которой пересылаются результаты. Все найденные записи нумеруются с 0. void * pBuf Адрес буфера для присылаемых записей. unsigned wBufSize Размер буфера для результатов. В буфер помещается целое количество записей. Если запись не может войти в буфер целиком, она не присылается. unsigned * cnt Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. Результат Тип Результат Значение hcERR равно 0. Операция успешно выполнена. При достижении конца результатов функция также возвращает 0, но и количество считанных байтов данных в этом случает возвращается нулевым. Не равно 0 Код ошибки. Причем ошибка ввода/вывода может возникнуть как на сервере при чтении данных, так и при передаче между сервером и прикладной программой. файл .h к этой DLL Скрытый текст /*************************************************************** Интерфейс к динамической библиотеке HSCLI.DLL Клиент (1.1.6.16) История: ======== 22.10.04 Тестовый вариант ***************************************************************/ #ifndef HSCLI_H_INCLUDED #define HSCLI_H_INCLUDED /* Для построения фиктивной DLL*/ #ifdef HSCLI_DUMMY_DLL #define HSCLI_DLL #define HSCLI_EOF { return 0; } #else #define HSCLI_EOF ; #endif #ifdef __cplusplus # define HSCLI_PFX extern "C" #else # define HSCLI_PFX #endif /* Функции, экспортируемые из DLL */ #if defined(HYCFG_SOLARIS) || defined(HYCFG_LINUX) # define HSCLI_FUN(type) HSCLI_PFX type # define HSCLI_CBK #elif defined(HYCFG_NETWARE) # ifdef HSCLI_DLL # define HSCLI_FUN(type) HSCLI_PFX type _export # define HSCLI_CBK # else # define HSCLI_FUN(type) HSCLI_PFX type # define HSCLI_CBK # endif #elif defined(HYCFG_WIN32) # ifdef HSCLI_DLL # define HSCLI_FUN(type) HSCLI_PFX type __declspec(dllexport) __stdcall # define HSCLI_CBK __stdcall # else # define HSCLI_FUN(type) HSCLI_PFX type __declspec(dllimport) __stdcall # define HSCLI_CBK __stdcall # endif #else # error !os #endif /* Ошибки локальной части */ #define SQL_RTL_LCL_REMOTE -20001 /* Ошибка связи */ #define SQL_RTL_LCL_USER_BREAK -20002 /* Обработка прервана пользователем */ #define SQL_RTL_LCL_NO_INIT -20003 /* Не инициализировано */ #define SQL_RTL_LCL_GENERAL_ERROR -20004 /* Другая ошибка */ #define SQL_RTL_LCL_BUSY -20005 /* Предыдущая операция не завершена */ #define SQL_RTL_LCL_NO_MEMORY -20006 /* Мало памяти */ #define SQL_RTL_LCL_TOO_MANY_SESSIONS -20007 /* Много сессий */ #define SQL_RTL_LCL_INV_ARG -20008 /* Неправильный аргумент */ #define SQL_RTL_LCL_TOO_OLD_SERVER -20009 /* Старый сервер */ /*************************************************************** Типы данных и константы ***************************************************************/ /* Идентификатор оператора */ typedef int hcHSTMT; /* Идентификатор соединения */ typedef int hcHDB; /* Номер поля */ typedef int hcFLD; /* Номер записи в таблице или результате */ typedef long hcRECNO; /* Обработчик записи */ typedef long hcRHANDLE; /* Код ошибки */ //#ifndef HSCLI_DLL typedef int hcERR; //#endif /* Функция обработки текстовых сообщений сервера */ typedef void HSCLI_CBK hcSqlCbkSrvMsgT(hcHDB conn, int is_err); typedef void HSCLI_CBK hcSqlCbkStmtSrvMsgT(hcHDB conn, hcHSTMT stmt, int is_err); /* Функция обработки Usersend */ typedef void HSCLI_CBK hcSqlCbkSrvUserSendT(hcHDB conn, int usertype); typedef void HSCLI_CBK hcSqlCbkStmtSrvUserSendT(hcHDB conn, hcHSTMT stmt, int usertype); /* Параметры инициализации */ typedef struct hcSqlParmT { unsigned size; /* Размер структуры */ } hcSqlParmT; /*************************************************************** Функции ***************************************************************/ /* Инициализировать клиентскую часть */ HSCLI_FUN(hcERR) hcSqlInit( hcSqlParmT *arg) /* Аргументы инициализации */ HSCLI_EOF /* Завершить работу */ HSCLI_FUN(hcERR) hcSqlDone(void) HSCLI_EOF /* Проверить завершение инициализации */ HSCLI_FUN(hcERR) hcSqlCheckInit(void) HSCLI_EOF /* Создать соединение */ HSCLI_FUN(hcERR) hcSqlAllocConnect( hcHDB *pdb) /* Соединение */ HSCLI_EOF /* Освободить соединение */ HSCLI_FUN(hcERR) hcSqlFreeConnect( hcHDB hdb) /* Соединение */ HSCLI_EOF /* Установить связь с сервером БД */ HSCLI_FUN(hcERR) hcSqlConnect( hcHDB hdb, /* Идентификатор соединения */ const char *server, const char *user, const char *password) HSCLI_EOF /* Разорвать связь с сервером БД */ HSCLI_FUN(hcERR) hcSqlDisconnect( hcHDB hdb) /* Идентификатор соединения */ HSCLI_EOF /* Получить информацию об соединении */ #define HSCLI_CONN_SRV_PATH 101 /* строка соединения (char[]) */ #define HSCLI_CONN_SRV_VERS 102 /* Версия сервера (double) */ #define HSCLI_CONN_SRV_VERS2 103 /* Версия сервера (char[]) */ #define HSCLI_CONN_USER_INFO 151 /* Информация пользователя (long) */ #define HSCLI_CONN_LCLADDR 152 /* Адрес (клиента) (char[]) */ #define HSCLI_CONN_RMTADDR 153 /* Адрес (сервера) (char[]) */ HSCLI_FUN(hcERR) hcSqlGetConnectAttr( hcHDB h, /* Идентификатор соединения */ unsigned option, /* Режим */ int pos, /* Позиция */ void *pValue, /* Буфер для значения */ unsigned size, /* и его размер */ unsigned *cnt) /* сколько байтов записали в буфер */ HSCLI_EOF #define HSCLI_ATTR_FLD_VERBOSE 1001 /* [conn/stmt] Расширенная информация о полях (int) */ #define HSCLI_ATTR_CONN_USER_INFO 1002 /* [conn/stmt] Информация пользователя (long) */ #define HSCLI_ATTR_CBK_SRVMSG 1100 /* [conn] Функция обработки сообщений сервера (hcSqlCbkSrvMsgT*) */ #define HSCLI_ATTR_CBK_SRVUSERSEND 1101 /* [conn] Функция обработки пользовательских сообщений сервера (hcSqlCbkSrvUserSendT*) */ #define HSCLI_ATTR_CBK_STMT_SRVMSG 1102 /* [stmt] Функция обработки сообщений сервера (hcSqlCbkStmtSrvMsgT*) */ #define HSCLI_ATTR_CBK_STMT_SRVUSERSEND 1103 /* [stmt] Функция обработки пользовательских сообщений сервера (hcSqlCbkStmtSrvUserSendT*) */ /* Изменение параметров соединения */ HSCLI_FUN(hcERR) hcSqlSetConnectAttr( hcHDB h, /* Идентификатор соединения */ unsigned option, /* Режим */ void *pValue, /* Значение (int/long) или буфер значения */ unsigned size) /* Размер значения в байтах или 0, если передаётся int/long */ HSCLI_EOF /* Сменить пароль пользователя * Результат: = 0 - успех, < 0 - ошибка */ HSCLI_FUN(hcERR) hcSqlAlterPassword( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя пользователя */ const char *oldpswd, /* Старый пароль */ const char *newpswd) /* Новый пароль */ HSCLI_EOF /* Создать пользователя * Результат: = 0 - успех, < 0 - ошибка */ HSCLI_FUN(hcERR) hcSqlCreateUser( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя пользователя */ const char *pswd, /* Пароль */ const char *profile, /* Профиль */ const char *startup) /* Стартовый файл */ HSCLI_EOF /* Создать Источник данных * Результат: = 0 - успех, < 0 - ошибка */ HSCLI_FUN(hcERR) hcSqlCreateDatasrc( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя источника */ const char *driver, /* Имя драйвера */ const char *user, /* имя пользователя */ const char *pswd) /* Пароль */ HSCLI_EOF /* Смена логина у источника данных * Результат: = 0 - успех, < 0 - ошибка */ HSCLI_FUN(hcERR) hcSqlAlterDatasrcLogin( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя источника */ const char *user, /* имя пользователя */ const char *pswd) /* Пароль */ HSCLI_EOF /* Создать оператор */ HSCLI_FUN(hcERR) hcSqlAllocStmt( hcHDB db, /* Соединение */ hcHSTMT *p) /* Место для номера оператора */ HSCLI_EOF /* Закрыть оператор */ HSCLI_FUN(hcERR) hcSqlFreeStmt( hcHSTMT h) /* Идентификатор оператора */ HSCLI_EOF /* Изменение параметров оператора */ HSCLI_FUN(hcERR) hcSqlSetStmtAttr( hcHSTMT h, /* Идентификатор оператора */ unsigned option, /* Режим */ void *pValue, /* Значение (int/long) или буфер значения */ unsigned size) /* Размер буфера или 0, если передаётся int/long */ HSCLI_EOF /* Странслировать и выполнить SQL-скрипт */ HSCLI_FUN(hcERR) hcSqlExecDirect( hcHSTMT h, /* Идентификатор оператора */ const char *text) /* Текст SQL-скрипта */ HSCLI_EOF /* Странслировать и выполнить SQL-скрипт */ HSCLI_FUN(hcERR) hcSqlExecDirectAsync( hcHSTMT h, /* Идентификатор оператора */ const char *text) /* Текст SQL-скрипта */ HSCLI_EOF /* Получить результат выполнения запроса */ HSCLI_FUN(hcERR) hcSqlExecDirectQuery( hcHSTMT h) /* Идентификатор оператора */ HSCLI_EOF /* Получить количество колонок результата */ HSCLI_FUN(hcERR) hcSqlNumResultCols( hcHSTMT h, /* Идентификатор оператора */ int *pCol) /* Место для количества колонок */ HSCLI_EOF /* Получить количество строк результата */ HSCLI_FUN(hcERR) hcSqlRowCount( hcHSTMT h, /* Идентификатор оператора */ hcRECNO *pCnt) /* Место для количества строк */ HSCLI_EOF /* Тип результата в операторе */ #define HSCLI_RES_NONE -1 /* Результата нет */ #define HSCLI_RES_RECORD 0 /* Результат содержит список записей */ #define HSCLI_RES_JOIN 3 /* Результат содержит результат слияния таблиц */ #define HSCLI_RES_SORTED 4 /* Результат содержит отсортированный список записей */ #define HSCLI_RES_GROUP 5 /* Результат содержит результаты операции группировки */ #define HSCLI_RES_SORTJOIN 6 /* Результат содержит отсортированное слияние таблиц */ /* Базовые типы данных в БД */ #define HSCLI_ET_CHAR 0 /* Массив символов длиной не более заданной */ #define HSCLI_ET_ARRA 1 /* Массив байтов заданной длины */ #define HSCLI_ET_BYTE 2 /* Элемент - unsigned char (короткое целое) */ #define HSCLI_ET_INTR 3 /* Элемент - signed short */ #define HSCLI_ET_WORD 4 /* Элемент - unsigned short */ #define HSCLI_ET_DATE 5 /* Дата - unsigned short */ #define HSCLI_ET_NMBR 6 /* Номер - 3-х байтовое целое без знака */ #define HSCLI_ET_LONG 7 /* Элемент - long int */ #define HSCLI_ET_DWRD 8 /* Элемент - unsigned long int */ #define HSCLI_ET_FLOA 9 /* Элемент - float */ #define HSCLI_ET_CURR 10 /* Деньги (double) */ #define HSCLI_ET_DFLT 11 /* Элемент - double */ #define HSCLI_ET_QINT 12 /* Элемент - signed __int64 */ #define HSCLI_ET_QWRD 13 /* Элемент - unsigned __int64 */ /* Ключевые поля в БД */ #define HSCLI_EK_NOTKEY 0 /* Элемент не ключ */ #define HSCLI_EK_COMMON 1 /* Обычный ключ */ #define HSCLI_EK_UNIQUE 2 /* Уникальный ключ */ #define HSCLI_EK_SURRGT 3 /* Суррогатный ключ */ /* Получить информацию об операторе */ #define HSCLI_STMT_SAB_TYPE 102 /* тип результата в SAB (int) */ #define HSCLI_STMT_SAB_HNDCNT 103 /* количество ht-обработчиков (int) */ #define HSCLI_STMT_SAB_HANDLES 104 /* ht-обработчики (int * i) */ #define HSCLI_STMT_ALS_CNT 105 /* количество alias-ов (int) */ typedef struct hcSqlAliasInfoT { int hthandle; char tname[32]; char aname[32]; } hcSqlAliasInfoT; #define HSCLI_STMT_ALS_INFO 106 /* информация об алиасах (aliasinfo * i) */ typedef struct hcSqlDstInfoT { int aliasno; int fieldno; int type; unsigned len; unsigned off; char coder[32]; char fname[32]; int func; char asname[32]; int key; int resno; } hcSqlDstInfoT; #define HSCLI_STMT_DST_INFO 107 /* Информация об колонке результата dst (dstinfo * i) */ #define HSCLI_STMT_RC_TYPE 109 /* Тип retcode (int) */ #define HSCLI_STMT_RC_SIZE 110 /* Длина retcode (int) */ #define HSCLI_STMT_RC_BODY 111 /* Значение retcode (char[], long, double) */ #define HSCLI_STMT_CURSNO 140 /* Номер курсора в HTSQL-сервере (int) */ HSCLI_FUN(hcERR) hcSqlGetStmtAttr( hcHSTMT h, /* Идентификатор оператора */ unsigned option, /* Режим */ int pos, /* Позиция */ void *pValue, /* Буфер для значения */ unsigned size, /* и его размер */ unsigned *cnt) /* сколько байтов записали в буфер */ HSCLI_EOF /* Открыть результаты для чтения. Читаются данные, отобранные * оператором select с учетом тех выражений, которые в нем заданы. */ HSCLI_FUN(hcERR) hcSqlOpenResults( hcHSTMT h, /* Оператор с результатами */ unsigned *pRecSize) /* Сюда запишется размер записи */ HSCLI_EOF /* Чтение результатов с указанной позиции */ HSCLI_FUN(hcERR) hcSqlReadResults( hcHSTMT h, /* Оператор с результатами */ hcRECNO gStart, /* С какой записи начинаем читать */ void *pBuf, /* Адрес буфера для результатов */ unsigned wBufSize, /* Размер буфера этого буфера */ unsigned *cnt) /* Сколько прочитали */ HSCLI_EOF /* Закрыть доступ к результатам */ HSCLI_FUN(hcERR) hcSqlCloseResults( hcHSTMT h) /* Оператор с результатами */ HSCLI_EOF /*************************************************************** "Странные" функции ***************************************************************/ /* Добавить элемент в результаты поиска * Доступ к исходным результатам должен быть открыт */ HSCLI_FUN(hcERR) hcSqlIncludeResultsItem( hcHSTMT h, /* Оператор с результатами */ hcRECNO gRecNo, /* Куда вставлять (от 0) */ /* RES_RECORD - физ.номер записи */ const void *pNewItem, /* Новый элемент результата: */ /* RES_SORTED - обработчик записи */ /* RES_JOIN - группа обработчиков записей для таблиц слияния */ /* RES_VALUE, RES_HISTO, RES_GROUP - тело элемента */ unsigned wLen) /* Длина нового элемента (в байтах) */ HSCLI_EOF /* Исключить элемент из результатов поиска * Доступ к исходным результатам должен быть открыт */ HSCLI_FUN(hcERR) hcSqlExcludeResultsItem( hcHSTMT h, /* Оператор с результатами */ hcRECNO gRecNo) /* Что удалять (от 0) */ /* RES_RECORD - физ.номер записи */ HSCLI_EOF /* Заменить элемент в результатах поиска * Доступ к исходным результатам должен быть открыт */ HSCLI_FUN(hcERR) hcSqlReplaceResultsItem( hcHSTMT h, /* Оператор с результатами */ hcRECNO gRecNo, /* Что менять (от 0) */ /* RES_RECORD - физ.номер записи */ const void *pNewItem, /* Новый элемент результата: */ /* RES_SORTED - обработчик записи */ /* RES_JOIN - группа обработчиков записей для таблиц слияния */ /* RES_VALUE, RES_HISTO, RES_GROUP - тело элемента */ unsigned wLen) /* Длина нового элемента (в байтах) */ HSCLI_EOF /* Считать элемент результата поиска - обработчик записи(ей) * Доступ к исходным результатам должен быть открыт * Допустим для результатов RES_RECORD, RES_SORTED и RES_JOIN */ /* Аналог функции htGetResultsItem */ HSCLI_FUN(hcERR) hcSqlGetResultsItem( hcHSTMT h, /* Оператор с результатами */ hcRECNO gRecNo, /* Что читать (от 0) */ /* RES_RECORD - физ.номер записи */ void *pItem, /* Длина элемента определяется типом результата: */ /* RES_SORTED - sizeof(RHANDLE) */ /* RES_JOIN - sizeof(RHANDLE) * число_таблиц_слияния */ unsigned bufsz) /* Длина буфера для чтения */ HSCLI_EOF /* "Освежить" результаты поиска (несортированные записи), привести */ /* их в соответствие с текущим состоянием таблицы. */ /* Доступ к исходным результатам должен быть закрыт */ HSCLI_FUN(hcERR) hcSqlStmtTouch( hcHSTMT h) /* Оператор с результатами */ HSCLI_EOF /* Удаление найденных записей из таблицы */ HSCLI_FUN(hcERR) hcSqlStmtDeleteResults( hcHSTMT h, /* Оператор с результатами */ long *cnt) /* Количество удалённых записей */ HSCLI_EOF /* Сортировка результатов в курсоре */ HSCLI_FUN(hcERR) hcSqlStmtSort( hcHSTMT h, /* Оператор с результатами */ int nFldCnt, /* Количество полей для сортировки */ hcFLD *pFields) /* Номера полей для сортировки */ HSCLI_EOF /* Определить подмножество записей таблицы, попавших в сортировку */ HSCLI_FUN(hcERR) hcSqlStmtUnsort( hcHSTMT h) /* Оператор с результатами */ HSCLI_EOF /*************************************************************** "Очень странные" функции ***************************************************************/ /* Добавление записи */ HSCLI_FUN(hcERR) hcSqlInsertRecord( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя таблицы */ unsigned len, /* Длина записи */ void *pRecord, /* Тело записи */ hcRECNO *pRecNo) /* Сюда запишется номер записи */ HSCLI_EOF /* Пакетное добавление */ HSCLI_FUN(hcERR) hcSqlAddRecords( hcHDB hdb, /* Идентификатор соединения */ const char *pName, /* Краткое имя таблицы */ hcRECNO gRecCount, /* Количество записей */ unsigned wRecSize, /* Размер записи */ const void *pBuf) /* Адрес буфера с телами записей */ HSCLI_EOF /* Получить запись с номером по обработчику */ HSCLI_FUN(hcERR) hcSqlReadRecordByHandle( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя таблицы */ hcRHANDLE hRecord, /* Обработчик записи */ void *pRecord, /* Адрес буфера для записи с номером */ unsigned bufsz) /* Размер буфера */ HSCLI_EOF /* Получить обработчик записи по физическому номеру */ HSCLI_FUN(hcERR) hcSqlHandleFromRecNo( hcHDB hdb, /* Идентификатор соединения */ const char *name, /* Имя таблицы */ hcRECNO gRecNo, /* Номер записи */ hcRHANDLE *record) HSCLI_EOF /* Модификация курсора */ #define HSCLI_OP_POSITION 1 /* Позиционирование и чтение */ #define HSCLI_OP_REFRESH 2 /* Чтение свежей записи */ #define HSCLI_OP_UPDATE 3 /* Модификация */ #define HSCLI_OP_DELETE 4 /* Удаление */ #define HSCLI_OP_INSERT 5 /* Вставка */ #define HSCLI_LOCK_BEFORE 0x0001 /* Захват записи перед операцией */ #define HSCLI_UNLOCK_AFTER 0x0002 /* Освобождение записи после операции */ #define HSCLI_LOCK_INTIME 0x0004 /* Захват записи во время операции */ #define HSCLI_RECORD_MAIN 0x0008 /* Захват только главной записи */ #define HSCLI_TWISE_ERROR 0x0010 /* Двойной захват - ошибка */ HSCLI_FUN(hcERR) hcSqlStmtEdit( hcHSTMT h, /* Оператор с результатами */ const char *pTab, /* Имя псевдонима таблицы в запросе или 0 */ hcRECNO row, /* Номер строки в курсоре (считается от 0) */ int op, /* Операция: HSSQL_OP_??? */ int lock, /* Захват, битовая маска, HS_LOCK/HS_UNLOCK */ void *buf, /* Адрес буфер записи */ unsigned sz, /* Размер буфера */ hcRECNO *recno) HSCLI_EOF /* Вставить в курсор несколько записей с указанными номерами */ HSCLI_FUN(hcERR) hcSqlFormRecordsSet( hcHSTMT h, /* Оператор с результатами */ const char *pName, /* Короткое имя таблицы, по которой надо создать курсор, или NULL */ hcRECNO gCnt, /* Количество вставляемых записей */ const hcRECNO *pRecordNo) /* Адрес массива с номерами записей */ HSCLI_EOF /* Чтение данных сообщения */ HSCLI_FUN(hcERR) hcSqlConnReadMsg( hcHDB hdb, /* Идентификатор соединения */ void *buf, /* Адрес буфер записи */ unsigned sz, /* Размер буфера */ unsigned *cnt) /* Сколько прочитали */ HSCLI_EOF /*************************************************************** Внутреннее представление данных ***************************************************************/ /* Упаковка даты */ /* 0 - неправильная дата */ HSCLI_FUN(unsigned short) hcSqlPackDate( unsigned day, /* День месяца (1-31) */ unsigned month, /* Месяц (1-12) */ unsigned year) /* Год (1900-2078) */ HSCLI_EOF /* Распаковка даты */ HSCLI_FUN(hcERR) hcSqlUnpackDate( unsigned short htdate, unsigned *day, unsigned *month, unsigned *year) HSCLI_EOF /* Выделение строки из поля, возвращается флаг потери информации */ HSCLI_FUN(int) hcSqlGetChar( char *dst, /* Буфер строки (с \0 символом в конце) */ unsigned dstlen, /* Длина буфера строки */ const unsigned char *field, /* Поле */ unsigned fldlen) /* Длина поля */ HSCLI_EOF /* Определение длины строки в поле */ HSCLI_FUN(unsigned) hcSqlGetCharLen( const unsigned char *field, /* Поле */ unsigned fldlen) /* Длина поля */ HSCLI_EOF /* Занесение строки в поле, возвращается флаг потери информации */ HSCLI_FUN(int) hcSqlSetChar( unsigned char *field, /* Поле */ unsigned fldlen, /* Длина поля */ const char *src) /* Исходная строка */ HSCLI_EOF /* Занесение null-значения */ HSCLI_FUN(hcERR) hcSqlSetNull( unsigned char *field, /* Поле */ int type, /* Тип поля (HSCLI_ET_???) */ unsigned typlen) /* Длина поля переменной длины */ HSCLI_EOF /* Проверка null-значения */ HSCLI_FUN(hcERR) hcSqlIsNull( const unsigned char *field, /* Поле */ int type, /* Тип поля (HSCLI_ET_???) */ unsigned typlen) /* Длина поля переменной длины */ HSCLI_EOF HSCLI_FUN(hcERR) hscliProcStart(void); HSCLI_FUN(hcERR) hscliProcExit(void); HSCLI_FUN(hcERR) hscliThrdStart(void); HSCLI_FUN(hcERR) hscliThrdExit(void); #endif пытаюсь исполнить вот так Скрытый текст // - - - - - - - - - - - - - - - --------------------------- Чтение результатов ----------------- hcRECNO gStart ; // С какой записи начинаем читать void *pBuf ; //Адрес буфера для присылаемых записей unsigned wBufSize ; // Размер буфера для результатов. unsigned *pCnt , hCnt ; // Сколько прочитали pCnt =&hCnt; cout << "\nФ-я hcSqlReadResults= " << hcSqlReadResults( hOper, gStart, &pBuf, wBufSize, pCnt); //---------------------------------------------------------------------------------------------------- Подскажите где у меня ошибка я вот не понимаю, если ты не знаешь как передавать аргументы в функцию, то имеет смысл открыть азы языка С++. Не? вот это убило unsigned *pCnt , hCnt ; // Сколько прочитали pCnt =&hCnt; |
Сообщ.
#4
,
|
|
|
Извините что долго не отвечал, если еще есть желание слушать , отвечу
эти смешные вещи взяты с других форумов , то там сям советовали собрал в кучу получилась такая солянка, но если еще интересно напишите как правильно , насчет того что я знаю или не , возможно чего то и знаю чего то не знаю но дело в том что пытаюсь по правильно не получается , может DLL-ка кривая, а может и че не догоняю поэтому я и думал что предназначение форумов , подсказать если есть желание , а если не хочется подсказывать то зачем лишний раз утруждаться напоминать мне что я тупой Добавлено Цитата Олег М @ А ты вообще эти переменным присваиваешь какие-нибудь значения перед вызовом? Или так и вызываешь? Если не затруднит посмотрите вот весь код Скрытый текст #define HYCFG_WIN32 #include "hscli.h" #include <iostream> using namespace std; int main() { setlocale(LC_ALL, "RUS"); hcSqlParmT init = { 0 }; init.size = sizeof(hcSqlParmT); hcHDB *pdb; // Адрес памяти, куда будет записан идентификатор созданного соединения. hcHDB hdb; // Идентификатор соединения. pdb = &hdb; hcHSTMT *pOper;// Адрес памяти, куда будет записан идентификатор созданного оператора. hcHSTMT hOper;// Место для идентификатора оператора pOper = &hOper; unsigned *pRecSize;// Адрес слова, в которое запишется размер читаемой записи в байтах. Если размер записи не нужен, то можно задать . unsigned hRecSize; pRecSize = &hRecSize; hcSqlInit(nullptr) ; // Инициализация клиентской части hcSqlCheckInit() ; // Проверка завершения инициализации hcSqlAllocConnect(pdb) ; // Создать соединение hcSqlConnect(hdb, "tcpip:/localhost:13000", "HTADMIN", "PASSWORD");//Установить связь с СУБД hcSqlAllocStmt(hdb, pOper); // Создать оператор hcSqlExecDirect(hOper, "fix all; select * from TABLES;");// Выполнение SQL-программы в указанном операторе hcSqlOpenResults(hOper, pRecSize);// Открытие результатов для чтения // - - - - - - - - - - - - - - - --------------------------- Чтение результатов --------------------------------- long gStart = 0 ; // С какой записи начинаем читать void *pBuf ; // Адрес буфера для присылаемых записей unsigned wBufSize = hRecSize; // Размер буфера для результатов. unsigned *pCnt, hCnt; // Сколько прочитали pCnt =&hCnt; hcSqlReadResults( hOper, gStart, &pBuf, wBufSize, pCnt); //for (unsigned i = 0; i < wBufSize; i++) // printf("%c", pBuf); //puts((char*)pBuf ); cout << pBuf; //------------------------------------------------------------------------------------------------------------------ hcSqlCloseResults(hOper); // Закрытие доступа к результатам hcSqlFreeConnect(hdb) ; // Освободить соединение hcSqlDone() ; // Завершение работы system("pause"); } Добавлено вот весь проект https://yadi.sk/d/7EHxbk-s3EvJEg |
Сообщ.
#5
,
|
|
|
Сообщ.
#6
,
|
|
|
Цитата kms @ ласс, теперь осталось чуть чуть , понять что с этим делать дальше А ты проверяешь значение, которое она возвращает, cnt. Мне кажется, эту функцию надо вызывать в цикле. Что-то типа char buf[1024] unsigned cnt = 0; for (hcRECNO rec = 0;; ++rec) { const auto res = hcSqlReadResults(hOper, rec, buf, sizeof(buf), &cnt); if (res != 0 || cnt == 0) break; ............ } Добавлено Цитата kms @ но дело в том что пытаюсь по правильно не получается , может DLL-ка кривая, а может и че не догоняю Может и кривая (есть не равная нулю вероятность), но ошибки, как правило, нужно в первую очередь искать в своём коде. А у тебя их там полно. Здесь надо делать примерно так unsigned res_size = 0; hcSqlOpenResults(hOper, &res_size);// Открытие результатов для чтения if (!res_size) ....return; std::unique_ptr<char[]> buf(new char[rec_size]); //char buf[rec_size]; - как вариант //Дальше цикл hcSqlReadResults(hOper, rec, buf.get(), rec_size, &cnt); И проверяй значения, которые возвращают функции. И сделай для начала простой запрос hcSqlExecDirect(hOper, "select * from TABLES"); |
Сообщ.
#7
,
|
|
|
Ребята вы представляете , к концу рабочего дня меня поперло , готово,
Прикреплённая картинка
Добавлено Если будет интересно скажите , выложу и проект и саму СУБД HyTech с тестовой таблицей (она 6Мб всего весит даже устанавливать не надо просто ложите папку на диск и запускаете ) Еще раз спасибо . А вот сам исходник Скрытый текст #define HYCFG_WIN32 #include "hscli.h" #include <iostream> using namespace std; int main() { setlocale(LC_ALL, "RUS"); // устанавливаем рус локаль hcSqlParmT *pInit; // Адрес структуры с параметрами инициализации типа hcSqlParmT. hcERR err; hcSqlParmT Init = { sizeof(Init) }; if ((err = hcSqlInit(&Init)) != 0) // Инициализация клиентской части { cout << "Ошибка с параметрами инициализации \n"; return 0; } if (hcSqlCheckInit() < 0 ) // Проверка завершения инициализации { cout << "Ошибка завершения инициализации \n"; return 0; } hcHDB *pdb; // Адрес памяти, куда будет записан идентификатор созданного соединения. hcHDB hdb; // Идентификатор соединения. pdb = &hdb; hcSqlAllocConnect(pdb); // Создать соединение hcSqlConnect(hdb, "tcpip:/localhost:13000", "HTADMIN", "PASSWORD");//Установить связь с СУБД hcHSTMT *pOper;// Адрес памяти, куда будет записан идентификатор созданного оператора. hcHSTMT hOper;// Место для идентификатора оператора pOper = &hOper; hcSqlAllocStmt(hdb, pOper); // Создать оператор hcSqlExecDirect(hOper, "fix all; select * from TABLES;");//Выполнение SQL в указанном операторе unsigned *pRecSize;// Адрес слова, в которое запишется размер читаемой записи в байтах. unsigned hRecSize; pRecSize = &hRecSize; hcSqlOpenResults(hOper, pRecSize);// Открытие результатов для чтения // - - - - - - - - - - - - - - - --------------------------- Чтение результатов --------------------------------- char buf[1024]; unsigned cnt = 0; long gStart = 0 ; // С какой записи начинаем читать void *pBuf ; // Адрес буфера для присылаемых записей unsigned wBufSize = hRecSize; // Размер буфера для результатов. hcSqlReadResults( hOper, gStart, buf, sizeof(buf), &cnt); // Чтение результатов //------------------------------------------------------------------------------------------------------------------ cout << buf; // выводим на экран hcSqlCloseResults(hOper); // Закрытие доступа к результатам hcSqlFreeConnect(hdb) ; // Освободить соединение hcSqlDone() ; // Завершение работы system("pause"); } |
Сообщ.
#8
,
|
|
|
Цитата kms @ Если будет интересно скажите , выложу и проект и саму СУБД HyTech с тестовой таблицей (она 6Мб всего весит даже устанавливать не надо просто ложите папку на диск и запускаете ) Еще раз спасибо . А вот сам исходник Про буфер посмотри, что я написал. buf[1024] - это неправильно. Да и вот эти ужасы убери, типа pRecSize = &hRecSize и pOper = &hOper. Там можно просто &hRecSize и &hOper передавать |
Сообщ.
#9
,
|
|
|
Вот СУБД HyTech https://yadi.sk/d/n60IIvqB3Evrbi распаковываете архив на D:\HyTech запускаете sql64.exe
Вот это проект под MSVS2015ExpressC++ https://yadi.sk/d/BojyvGhy3EvraF тут без слов , делайте че хотите А это так комплект если будете делать на чем нибудь другом https://yadi.sk/d/8jSH-YgD3EvrcP Добавлено Олег М извини , я чето прозевал все твои сообщения , щас разбираю по новой и буду коректировать Добавлено Цитата Олег М @ Мне кажется, эту функцию надо вызывать в цикле. Что-то типа Да я это чувствую , это и будет вторым шагом , Цитата Олег М @ Может и кривая (есть не равная нулю вероятность), но ошибки, как правило, нужно в первую очередь искать в своём коде. А у тебя их там полно. DLL-ка оказалась не кривой , |
Сообщ.
#10
,
|
|
|
Цитата kms @ Вот СУБД HyTech https://yadi.sk/d/n60IIvqB3Evrbi распаковываете архив на D:\HyTech запускаете sql64.exe Знаешь, с тем кодом, который ты показываешь, это не слишком хорошая реклама для субд. Кроме того я там так и не понял как разобрать запись по полям. |
Сообщ.
#11
,
|
|
|
Цитата Олег М @ Знаешь, с тем кодом, который ты показываешь, это не слишком хорошая реклама для субд. какая же это реклама , и при чем тут моя стряпня имеет к этой СУБД, это тоже самое что если я возму хорошую краску нарисую хрень на заборе , а судить будут производителя краски ) я пробую что то сделать , а уже вопрос второй под что на что для чего, СУБД сама по сибе и я к ней ни с какого бока |
Сообщ.
#12
,
|
|
|
сейчас делаю вот так
Цитата Олег М @ Здесь надо делать примерно так unsigned res_size = 0; hcSqlOpenResults(hOper, &res_size);// Открытие результатов для чтения if (!res_size) ....return; std::unique_ptr<char[]> buf(new char[rec_size]); //char buf[rec_size]; - как вариант //Дальше цикл hcSqlReadResults(hOper, rec, buf.get(), rec_size, &cnt); но что то конструктор unique_ptr не хочет конструировать |
Сообщ.
#13
,
|
|
|
Цитата kms @ но что то конструктор unique_ptr не хочет конструировать В смысле? Покажи свой код |
Сообщ.
#14
,
|
|
|
char buf[1024]; std::unique_ptr<char[]> buf(new char[pRecSize]); unsigned cnt = 0; long gStart = 0 ; // С какой записи начинаем читать void *pBuf ; // Адрес буфера для присылаемых записей hcSqlReadResults(hOper, gStart, buf.get(), pRecSize, &cnt); // Чтение результатов Добавлено Ошибка namespace "std" не содержит члена "unique_ptr" Добавлено а вот так работает но вывод немного не полный char buf[1024]; //std::unique_ptr<char[]> buf(new char[pRecSize]); unsigned cnt = 0; long gStart = 0 ; // С какой записи начинаем читать void *pBuf ; // Адрес буфера для присылаемых записей hcSqlReadResults(hOper, gStart, buf , pRecSize, &cnt); // Чтение результатов for (long rec = 0;; ++rec) { const auto res = hcSqlReadResults(hOper, rec, buf, sizeof(buf), &cnt); if (res != 0 || cnt == 0) break; cout << buf; // выводим на экран } |
Сообщ.
#15
,
|
|
|
Сообщ.
#16
,
|
|
|
Цитата kms @ Ошибка namespace "std" не содержит члена "unique_ptr" Сделай #include <memory> Добавлено Цитата kms @ cout << buf; // выводим на экран А ты уверен, что там возвращается именно строка, с нулем на конце, а не бинарные данные? |
Сообщ.
#17
,
|
|
|
да и еще , избавится от конструкции
hcHDB *pdb; // Адрес памяти, куда будет записан идентификатор созданного соединения. hcHDB hdb; // Идентификатор соединения. pdb = &hdb; не получается Добавлено Цитата Олег М @ Кроме того я там так и не понял как разобрать запись по полям. там есть еще функции hcERR hcSqlNumResultCols( hcHSTMT h, /* Номер оператора */ int *pCol); /* Место для количества колонок */ hcERR hcSqlRowCount( hcHSTMT h, /* Номер оператора */ hcRECNO *pCnt); /* Место для количества строк */ и самое главное вот это http://hytechdb.ru/index.php?s=docs&ru=V25...GetStmtAttr.htm Добавлено Цитата Олег М @ Сделай #include <memory> ОК я еще добавил int pCol=0; // Место для количества колонок hcRECNO pStr=0; // Место для количества строк hcSqlNumResultCols(hOper, &pCol); // Получить количество колонок результата hcSqlRowCount(hOper, &pStr); // Получить количество строк результата |
Сообщ.
#18
,
|
|
|
Цитата kms @ да и еще , избавится от конструкции hcHDB *pdb; // Адрес памяти, куда будет записан идентификатор созданного соединения. hcHDB hdb; // Идентификатор соединения. pdb = &hdb; не получается Почему? Добавлено Ну да, что-то похожее на способ получения информации о столбцах. Чтоб разобрать данные, которые вернулись из hcSqlReadResults |
Сообщ.
#19
,
|
|
|
Цитата Олег М @ да и еще , избавится от конструкции hcHDB *pdb; // Адрес памяти, куда будет записан идентификатор созданного соединения. hcHDB hdb; // Идентификатор соединения. pdb = &hdb; не получается Почему? Слушай , попробовал по третьему разу и получилось, #define HYCFG_WIN32 #include "hscli.h" #include <iostream> #include <memory> using namespace std; int main() { setlocale(LC_ALL, "RUS"); // устанавливаем рус локаль hcSqlParmT *pInit; // Адрес структуры с параметрами инициализации типа hcSqlParmT. hcERR err; hcSqlParmT Init = { sizeof(Init) }; if ((err = hcSqlInit(&Init)) != 0) // Инициализация клиентской части { printf( "Ошибка с параметрами инициализации \n"); return 0; } if (hcSqlCheckInit() < 0 ) // Проверка завершения инициализации { printf( "Ошибка завершения инициализации \n" ); return 0; } hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcSqlAllocConnect( &pdb); // Создать соединение hcSqlConnect( pdb, "tcpip:/localhost:13000", "HTADMIN", "PASSWORD");//Установить связь с СУБД hcHSTMT pOper;// Адрес памяти, куда будет записан идентификатор оператора. hcSqlAllocStmt(pdb, &pOper); // Создать оператор hcSqlExecDirect(pOper, "fix all; select * from TABLES;");//Выполнение SQL в указанном операторе int pCol=0; // Место для количества колонок hcRECNO pStr=0; // Место для количества строк hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата hcSqlRowCount(pOper, &pStr); // Получить количество строк результата unsigned pRecSize = 0 ;// Адрес слова, в которое запишется размер читаемой записи в байтах. hcSqlOpenResults(pOper, &pRecSize);// Открытие результатов для чтения if (!pRecSize) return 0; // - - - - - - - - - - - - - - - --------------------------- Чтение результатов -------------------- std::unique_ptr<char[]> buf(new char[pRecSize]); unsigned cnt = 0; long gStart = 0 ; // С какой записи начинаем читать void *pBuf ; // Адрес буфера для присылаемых записей for (long rec = 0; rec < pStr ; rec++) { hcSqlReadResults(pOper, rec, buf.get(), pRecSize, &cnt); // Чтение результатов printf("%s\n", buf); // выводим на экран } //------------------------------------------------------------------------------------------------------- hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb) ; // Освободить соединение hcSqlDone() ; // Завершение работы system("pause"); } и выхлоп Прикреплённая картинка
|
Сообщ.
#20
,
|
|
|
Цитата kms @ printf("%s\n", buf); // выводим на экран Это неправильно, надо делать buf.get(). Там можно было сделать std::cout << buf.get() << std::endl; Ну и ты не ответил вопрос насчёт строки. Попробуй там сделать select *, 123 from TABLES; Добавлено Включи в компиляторе warnings, полный уровень. Там у тебя наверняка сругается на этот printf. |
Сообщ.
#21
,
|
|
|
Цитата Олег М @ Это неправильно, надо делать buf.get(). Там можно было сделать std::cout << buf.get() << std::endl; ОК, переделал , работает Добавлено Цитата Олег М @ Ну и ты не ответил вопрос насчёт строки. Попробуй там сделать select *, 123 from TABLES; Насчет строки я думаю и пробую с самого начала, но в отладчике конкретно не видно , т.е. если в начале когда не чего не получалось , смотрел переменную buf там было 0х000000000 ,а теперь выхожу по точке останова в цикле и выставляю контрольное значение на buf и там показывает - (buf)._Mypair._Myval2 0x00bb2290 "AVER HTADMIN BASE TABLE C:\\HyTech\\DB\\AVER ... char * Добавлено Конструкция select *, 123 from TABLES; для SQL HyTech ошибочна, потому что он не может добавить после вывода всех полей еще поле со значением "123", а вот select 123 from TABLES; дает вывод на консоль { (одна скобка), и вот что в отладчике - (buf)._Mypair._Myval2 0x00735bc0 "{" char * |
Сообщ.
#22
,
|
|
|
Цитата kms @ ,а теперь выхожу по точке останова в цикле и выставляю контрольное значение на buf и там показывает Ты там не выставишь контрольное значение на uniqueptr. Сделай select, который я написал и посмотри, что выведется на экран Добавлено Цитата kms @ а вот select 123 from TABLES; дает вывод на консоль { (одна скобка), и вот что в отладчике Сделай на всякий случай не 123, а чтонибудь другое. Но, похоже там возвращается не строка, а байтовый массив, который надо разбирать по определенным правилам |
Сообщ.
#23
,
|
|
|
Цитата Олег М @ не возможно сделать ошибка HyTEch: -1018 , и прога вываливается Сделай select, который я написал и посмотри, что выведется на экран Добавлено Цитата Олег М @ Сделай на всякий случай не 123, а чтонибудь другое. делаю fix all; select 'www' from TABLES; выхлоп wwwээээ Добавлено делаю делаю fix all; select 'www' from TABLES; выхлоп в консоль wwwQQQээээ т.е. добавляется ээээ в конце строки Добавлено если убираю //setlocale(LC_ALL, "RUS"); // рус локаль то выхлоп www¤¤¤¤ |
Сообщ.
#24
,
|
|
|
Цитата kms @ т.е. добавляется ээээ в конце строки Т.е. это не строка, а байтовый массив. Надо получать тип данных для каждой колонки и обрабатывать соответственно. |
Сообщ.
#25
,
|
|
|
Вот еще один момент , при запросе к TABLES возвращается все поля строкового типа, а вот если делаю запрос к другой таблице , например подобрал всего с двумя полями с одной строкой , делаю
hcSqlExecDirect(pOper, "fix all; select * from AVER;");//Выполнение SQL в указанном операторе выхлоп при включеной setlocale(LC_ALL, "RUS"); ╬fffffц4@¤¤¤¤▌▌я♥1◄▌▌ выхлоп при отключенной setlocale(LC_ALL, "RUS"); ╬fffffц4@¤¤¤¤▌▌ J┤4▌▌ в реальности там лежат цифры 1998 20,9 1998 - в БД представлено именно как int Добавлено Цитата Олег М @ Т.е. это не строка, а байтовый массив. Надо получать тип данных для каждой колонки и обрабатывать соответственно. да так оно и есть , только я не могу пока понять как , я смотрю сейчас на остальные функции //Ф-ция Получить информацию об соединении hcERR hcSqlGetConnectAttr( hcHDB h, /* Идентификатор соединения */ unsigned option, /* Режим */ int pos, /* Позиция */ void *pValue, /* Буфер для значения */ unsigned size, /* и его размер */ unsigned *cnt); /* сколько байтов записали в буфер */ Добавлено Вот нашел, копипастить сюда не буду просто ссылка http://hytechdb.ru/index.php?s=docs&ru=V25...GetStmtAttr.htm тут есть такой момент в функции hcERR hcSqlGetStmtAttr( hcHSTMT h, /* Идентификатор оператора */ unsigned option, /* Режим */ int pos, /* Позиция */ void *pValue, /* Буфер для значения */ unsigned size, /* и его размер */ unsigned *cnt); /* сколько байтов записали в буфер */ описание параметра option Идентификатор параметра оператора, который меняем. Параметр option может принимать следующие значения: HSCLI_STMT_SAB_TYPE — Тип результата HSSQL_STMT_SAB_HNDCNT — Количество hytech-обработчиков HSSQL_STMT_SAB_HANDLES — hytech-обработчики HSCLI_STMT_ALS_CNT — Количество алиасов HSCLI_STMT_ALS_INFO — информация об алиасах HSCLI_STMT_DST_INFO — Информация об колонке результата HSCLI_STMT_RC_TYPE — Тип возвращаемого значения HSCLI_STMT_RC_SIZE — Длина возвращаемого значения в байтах HSCLI_STMT_RC_BODY — Возвращаемое значение так вот в частности значение HSCLI_STMT_DST_INFO — Информация об колонке результата и там его описание вот сейчас я и пробую эту ф-цию Добавлено делаю так unsigned option; // Режим int pos; // Позиция void pValAttr;//Адрес буфера памяти, в которую будут записаны значение (значения) параметра соединения. unsigned sizeAttr;// и его размер unsigned cntAttr;// сколько байтов записали в буфер hcSqlGetConnectAttr(pdb, option, pos, &pValAttr, sizeAttr, &cntAttr ); // Получить информацию об соединении ругается ОшибкаC2182pValAttr: недопустимое использование типа "void"AdmHyTechc:\users\admin\desktop\admhytech\admhytech\main.cpp35 |
Сообщ.
#26
,
|
|
|
Цитата kms @ ОшибкаC2182pValAttr: недопустимое использование типа "void"AdmHyTechc:\users\admin\desktop\admhytech\admhytech\main.cpp35 Я так и не понял ты переменные инициализируешь, присваиваешь им какие-то значения? Думаю там должно быть что-то вроде { hcErr err = 0; int nCols = 0; err = hcSqlNumResultCols(pdb, &nCols); if (!err && nCols) { cSqlDstInfoT cols[nCols] = {0}; //Либо, если так не скомпилится std::unique_ptr<cSqlDstInfoT> spCols(new cSqlDstInfoT[nCols]); unsigned n = 0; err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, cols /*spCols.get()*/, nCols * sizeof(cSqlDstInfoT), n); if (err) { std::err << "error" << std::endl; return; } for (int i = 0; i < n / sizeof(cSqlDstInfoT); ++i) { const auto &col = cols[i]; //Здесь разобрать буфер в зависимости от содержимого col } } |
Сообщ.
#27
,
|
|
|
ОК сейчас пробую
Добавлено Попробывал так static int xK = pCol; if (pCol) { unique_ptr<hcSqlDstInfoT> spCols(new hcSqlDstInfoT[pCol]); hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, spCols.get(), pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе for (int i = 0; i < cntOp / sizeof(hcSqlDstInfoT); ++i) { cout << spCols.get(); //Здесь разобрать буфер } } Добавлено Помоему изначально надо void* , как написано в описании к функции и в заголовочном файле HSCLI_FUN(hcERR) hcSqlGetStmtAttr( hcHSTMT h, /* Идентификатор оператора */ unsigned option, /* Режим */ int pos, /* Позиция */ void *pValue, /* Буфер для значения */ unsigned size, /* и его размер */ unsigned *cnt) /* сколько байтов записали в буфер */ HSCLI_EOF Добавлено Вот еще у них на сайте к описанию этой функции есть пример int cnt = 0; /* получим количество обработчиков */ if(hcSqlGetStmtAttr(pdb, HSSQL_STMT_SAB_HNDCNT, 0, &cnt, sizeof(cnt), 0) != 0) return; /* здесь надо обработать ошибку */ for(i = 0; i < cnt; i++) { int h; /* получаем очередной обработчик */ if(hcSqlGetStmtAttr(pdb, HSSQL_STMT_SAB_HANDLES, i, &h, sizeof(h), 0) != 0) return; /* здесь надо обработать ошибку */ printf("%ld ", h); } сейчас его пробую Добавлено не это вообще не о том |
Сообщ.
#28
,
|
|
|
Цитата kms @ Помоему изначально надо void* , как написано в описании к функции и в заголовочном файле К указателю на void преобразовывается любой указатель. Передавать же туда надо указатель на переменную, тип которой зависит от параметра option (там ниже описано, что именно). В параметре size передаётся sizeof() этой переменной (НЕ УКАЗАТЕЛЯ НА НЕЁ!). |
Сообщ.
#29
,
|
|
|
Понял но не совсем , если с начала , надо получить информацию об операторе, делаю так:
unsigned optionOp = 107;// Режим int posOp = 1 ; // Позиция void *pValueOp; // Буфер для значения unsigned sizeOp = 1024; // и его размер unsigned cntOp=0 ; // сколько байтов записали в буфер hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, posOp, &pValueOp, sizeof(pValueOp), &cntOp); // Получить информацию об операторе printf("%ld ", pValueOp ); Прикреплённая картинка
Добавлено вот в эту переменную void *pValueOp; // Буфер для значения что записывается ? Добавлено В описании к функции написано const void * (выходной)pValueАдрес буфера памяти, в которую будут записаны значение (значения) параметра оператора. |
Сообщ.
#30
,
|
|
|
Цитата kms @ вот в эту переменную void *pValueOp; // Буфер для значения Я ж те вроде написал как сделать, сделай также. Там должен быть указатель на одну или несколько структур hcSqlDstInfoT Добавлено А как у тебя получилось одинаковое количество колонок и строк, ты там точно ничего не перепутал? |
Сообщ.
#31
,
|
|
|
858993460 вот это число которое вывелось с pValueOp, я так понимаю адрес ??? или нет
|
Сообщ.
#32
,
|
|
|
Цитата kms @ 858993460 вот это число которое вывелось с pValueOp, я так понимаю адрес ??? или нет Это какой-то мусор |
Сообщ.
#33
,
|
|
|
Цитата Олег М @ А как у тебя получилось одинаковое количество колонок и строк, ты там точно ничего не перепутал? я поставил в запросе другую таблицу на 10 колонок и 10 строк Добавлено Цитата Олег М @ Это какой-то мусор ага понял щас пробую как ты написал |
Сообщ.
#34
,
|
|
|
Цитата kms @ я поставил в запросе другую таблицу на 10 колонок и 10 строк Поставь лучше разные, чтоб не перепутать. А то ты можешь. |
Сообщ.
#35
,
|
|
|
hcSqlDstInfoT cols[pCol] = { 0 }; hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, cols /*spCols.get()*/, pCol * sizeof(hcSqlDstInfoT), &cntOp); hcSqlDstInfoT cols[pCol] = { 0 }; ругается "Выражение должно иметь константное значение" показывает на pCol Добавлено Цитата Олег М @ Поставь лучше разные, чтоб не перепутать. А то ты можешь. ага понял щас |
Сообщ.
#36
,
|
|
|
Цитата kms @ угается "Выражение должно иметь константное значение" показывает на pCol Какой у тебя компилятор? И как объявлена pCol? |
Сообщ.
#37
,
|
|
|
Эти префиксы - p, n, sp и т.д. не просто так ставятся, от фонаря. Это т.н. венгерская нотация, почитай. В твоём случае переменную лучше назвать nCols
|
Сообщ.
#38
,
|
|
|
MSVC 2015 Express
hcHSTMT pOper;// Адрес памяти, куда будет записан идентификатор оператора. hcSqlAllocStmt(pdb, &pOper); // Создать оператор hcSqlExecDirect(pOper, "fix all; select * from AVER;");//Выполнение SQL в указанном операторе int pCol = 0; // Место для количества колонок hcRECNO pStr = 0; // Место для количества строк hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата hcSqlRowCount(pOper, &pStr); // Получить количество строк результата cout << "Кол-во колонок " << pCol << endl; cout << "Кол-во строк " << pStr << endl; unsigned optionOp = 107;// Режим int posOp = 1 ; // Позиция void *pValueOp; // Буфер для значения unsigned sizeOp = 1024; // и его размер unsigned cntOp ; // сколько байтов записали в буфер hcSqlDstInfoT cols[] = { 0 }; hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, cols /*spCols.get()*/, pCol * sizeof(hcSqlDstInfoT), &cntOp); да вот сделал так cols[] нашел щас в старом справочнике Если мы явно указываем список значений, то можем не указывать размер массива: компилятор сам подсчитает количество элементов: Добавлено по крайней мере сейчас компилируется без ошибок |
Сообщ.
#39
,
|
|
|
Цитата kms @ да вот сделал так cols[] Вообще неправильно. Даже не знаю, что это получилось. Сделай через unique_ptr. |
Сообщ.
#40
,
|
|
|
к предыдущему коду (в посте#38) добавил
for (int i = 0; i < cntOp / sizeof(hcSqlDstInfoT); ++i) { const auto &col = cols[i]; //printf(" %ld ", cols[i] ); //Здесь разобрать буфер в зависимости от содержимого col } а hcSqlDstInfoT cols[2] = { 0 }; поставил для эксперимента cols[2] принудительно "2", чтобы посмотреть че будет. Срабатывает, даже если раскаментирую printf(" %ld ", cols[i] ); тоже срабатывает и даже успеваю увидеть мелькает консоль и выводится несколько строк цыфр двухзначных, и следом окно ошибка Необработанное исключение по адресу 0x009380D0 в AdmHyTech.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0x003B0000. |
Сообщ.
#41
,
|
|
|
Во-первых, если ты сделал cols[2] - то вместо pCol * sizeof(hcSqlDstInfoT) надо сделать sizeof(cols)
Во-вторых, посмотри, что возвращается в cntOp |
Сообщ.
#42
,
|
|
|
что возвращается в cntOp --- 3435973836
Цитата Олег М @ Во-первых, если ты сделал cols[2] - то вместо pCol * sizeof(hcSqlDstInfoT) надо сделать sizeof(cols) сделал , а теперь как правильно проконтролировать результат , вывести что там в cols[i] |
Сообщ.
#43
,
|
|
|
std::cout << "aliasno = " << cols[i].aliasno << std::endl;
std::cout << "fieldno = " << cols[i].fieldno << std::endl; //И так далее для всех полей hcSqlDstInfoT |
Сообщ.
#44
,
|
|
|
Сообщ.
#45
,
|
|
|
Цитата Олег М @ Во-вторых, посмотри, что возвращается в cntOp Что там? |
Сообщ.
#46
,
|
|
|
вообщем сейчас вот так , что бы не запутаться , вот код (написал вывод всех полей структуры, )
hcSqlDstInfoT cols[] = { 0 }; hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, cols, sizeof(cols), &cntOp); for (int i = 0; i < cntOp / sizeof(hcSqlDstInfoT); ++i) { const auto &col = cols[i]; std::cout << "aliasno = " << cols[i].aliasno << std::endl; std::cout << "fieldno = " << cols[i].fieldno << std::endl; cout << "type = " << cols[i].type << endl; cout << "len = " << cols[i].len << endl; cout << "off = " << cols[i].off << endl; for (int x = 0; x < 32;x++) cout << "coder = " << cols[i].coder[x] << endl; for (int x = 0; x < 32; x++) cout << "fname = " << cols[i].fname[x] << endl; cout << "func = " << cols[i].func << endl; for (int x = 0; x < 32; x++) cout << "asname = " << cols[i].asname[x] << endl; cout << "key = " << cols[i].key << endl; cout << "resno = " << cols[i].resno << endl; //Здесь разобрать буфер в зависимости от содержимого col } вот выхлоп успеваю даже скрин снять Прикреплённая картинка
Добавлено и в дебаге показывает asname идентификатор "asname" не определен Добавлено Цитата Олег М @ Что там? я же писал там 3435973836 Добавлено а вот это 26843545 получается после cntOp / sizeof(hcSqlDstInfoT) |
Сообщ.
#47
,
|
|
|
Цитата kms @ вообщем сейчас вот так , что бы не запутаться , вот код (написал вывод всех полей структуры, ) Этот код вообще левый, на выхлоп можно даже не смотреть Добавлено Посмотри для начала sizeof(cols) Потом сделай hcSqlDstInfoT cols = { 0 };, убери квадратные скобки, а в вызове фунции сделай &cols Потом посмотри, какую ошибку возвращает err = hcSqlGetStmtAttr Потом cntOp Добавлено Цитата kms @ я же писал там 3435973836 Это явно что–то не то, мусор Добавлено Цитата kms @ я же писал там 3435973836 Где ты об этом писал? |
Сообщ.
#48
,
|
|
|
cout << sizeof(cols) << endl; --- 128
cout << err << endl; --- -93 по справочнику "Список кодов ошибок SQL HyTech" Ошибки при выполнении Маленький буфер Для информации выделен слишком маленький буфер. cout << cntOp << endl; --- 3435973836 |
Сообщ.
#49
,
|
|
|
Цитата Олег М @ Потом сделай hcSqlDstInfoT cols = { 0 };, убери квадратные скобки, а в вызове фунции сделай &cols Сделал? Добавлено А вообще, сделай–ка с unique_ptr, как я там в комментариях писал. И все остальное проверь тоже. И код покажи. |
Сообщ.
#50
,
|
|
|
Сейчас , делаю
|
Сообщ.
#51
,
|
|
|
Скрытый текст #define HYCFG_WIN32 #include "hscli.h" #include <iostream> #include <memory> using namespace std; int main() { setlocale(LC_ALL, "RUS"); // рус локаль hcERR err; hcSqlParmT Init = { sizeof(Init) }; //// Адрес структуры с параметрами инициализации if((err = hcSqlInit(&Init)) != 0) {/* Инициализация клиентской части */ printf("Ошибка с параметрами инициализации \n"); return 0; } if(hcSqlCheckInit() < 0) { /* Проверка завершения инициализации */ printf("Ошибка завершения инициализации \n"); return 0; } hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcSqlAllocConnect(&pdb); // Создать соединение hcSqlConnect(pdb, "tcpip:/localhost:13000", "HTADMIN", "PASSWORD");//Установить связь с СУБД unsigned optionAttr = 101; // Режим int pos = 1; // Позиция Некоторые параметры могут представлять собой массив значений. Параметр pos определяет, какую порцию значений прикладная программа хочет прочитать. void *pValAttr=NULL;//Адрес буфера памяти, в которую будут записаны значение (значения) параметра соединения. unsigned sizeAttr = 1024;// и его размер unsigned cntAttr; // сколько байтов записали в буфер hcSqlGetConnectAttr(pdb, optionAttr, pos, pValAttr, sizeAttr, &cntAttr);// Получить информацию о соединении hcHSTMT pOper;// Адрес памяти, куда будет записан идентификатор оператора. hcSqlAllocStmt(pdb, &pOper); // Создать оператор hcSqlExecDirect(pOper, "fix all; select * from TAB;");//Выполнение SQL в указанном операторе TABLES USERSPEC int pCol = 0; // Место для количества колонок hcRECNO pStr = 0; // Место для количества строк hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата hcSqlRowCount(pOper, &pStr); // Получить количество строк результата std::cout << "Кол-во колонок pCol = " << pCol << endl; std::cout << "Кол-во строк pStr = " << pStr << endl; //--------------------------------? ? ? ? ? ? П О Л У Ч И Т Ь И Н Ф О Р М А Ц И Я ? ? ? ? ------ unsigned optionOp = 107; // Режим int posOp = 1 ; // Позиция void *pValueOp; // Буфер для значения unsigned sizeOp = 1024; // и его размер unsigned cntOp ; // сколько байтов записали в буфер hcSqlDstInfoT Kol = { sizeof(Kol) };// Структура Информация о колонке результата hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, &Kol, sizeof(Kol), &cntOp);// Получить информацию об операторе for (int i = 0; i < cntOp / sizeof(hcSqlDstInfoT); i++) { } std::cout << "код ошибки при получении информации об операторе " << err << endl; std::cout << "размер sizeof(Kol) = " << sizeof(Kol) << endl; std::cout << "кол-во байтов записаных в буфер Оператора cntOp = " << cntOp << endl; std::cout << "размер sizeof(hcSqlDstInfoT) = " << cntOp << endl; std::cout << "cntOp / sizeof(hcSqlDstInfoT) = " << cntOp / sizeof(hcSqlDstInfoT) << endl; std::cout << "-----------------------------------------------------------------" << endl; std::cout << "Вывод результата запроса select * from TAB; (в таблице 4строки 2столбца)" << endl; std::cout << "------------------------------------------------------------------------" << endl; //------------------------------- Ч Т Е Н И Е Р Е З У Л Ь Т А Т О В ---------------------------- unsigned pRecSize = 0;// Адрес слова, в которое запишется размер читаемой записи в байтах. hcSqlOpenResults(pOper, &pRecSize);// Открытие результатов для чтения long gStart = 0; // С какой записи начинаем читать unique_ptr<char[]> buf(new char[pRecSize]); unsigned cnt = 0; // Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. for ( ; gStart < pStr; gStart++) { hcSqlReadResults(pOper, gStart, buf.get(), pRecSize, &cnt); // Чтение результатов std::cout << buf.get() << endl;// } //----------------------------------------------------------------------------------------------- std::cout << "------------------------------------------------------------------------" << endl; hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы std::system("pause"); } Прикреплённая картинка
|
Сообщ.
#52
,
|
|
|
Цитата kms @ hcSqlDstInfoT Kol = { sizeof(Kol) };// Структура Информация о колонке результата Это что? Должно быть hcSqlDstInfoT Kol = {0} Цитата kms @ hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, &Kol, sizeof(Kol), &cntOp);// Получить информацию об операторе Ты там ниже выводишь код ошибки от предыдущей операции, надо сделать err = hcSqlGetStmtAttr...... Добавлено Цитата kms @ for (int i = 0; i < cntOp / sizeof(hcSqlDstInfoT); i++) Это закоментарь пока, да и всё что ниже. Сделай только вывод значения err и cntOp. Надо сначала разобраться с ними, в смысле с hcSqlGetStmtAttr |
Сообщ.
#53
,
|
|
|
ОК смотри, что получилось :
Скрытый текст #define HYCFG_WIN32 #include "hscli.h" #include <iostream> #include <memory> using namespace std; int main() { setlocale(LC_ALL, "RUS"); // рус локаль hcERR err; hcSqlParmT Init = { sizeof(Init) }; //// Адрес структуры с параметрами инициализации if((err = hcSqlInit(&Init)) != 0) {/* Инициализация клиентской части */ printf("Ошибка с параметрами инициализации \n"); return 0; } if(hcSqlCheckInit() < 0) { /* Проверка завершения инициализации */ printf("Ошибка завершения инициализации \n"); return 0; } hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcSqlAllocConnect(&pdb); // Создать соединение hcSqlConnect(pdb, "tcpip:/localhost:13000", "HTADMIN", "PASSWORD");//Установить связь с СУБД unsigned optionAttr = 101; // Режим int pos = 1; // Позиция Некоторые параметры могут представлять собой массив значений. Параметр pos определяет, какую порцию значений прикладная программа хочет прочитать. void *pValAttr=NULL;//Адрес буфера памяти, в которую будут записаны значение (значения) параметра соединения. unsigned sizeAttr = 1024;// и его размер unsigned cntAttr; // сколько байтов записали в буфер hcSqlGetConnectAttr(pdb, optionAttr, pos, pValAttr, sizeAttr, &cntAttr);// Получить информацию о соединении hcHSTMT pOper;// Адрес памяти, куда будет записан идентификатор оператора. hcSqlAllocStmt(pdb, &pOper); // Создать оператор hcSqlExecDirect(pOper, "fix all; select * from TAB;");//Выполнение SQL в указанном операторе TABLES USERSPEC int pCol = 0; // Место для количества колонок hcRECNO pStr = 0; // Место для количества строк hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата hcSqlRowCount(pOper, &pStr); // Получить количество строк результата std::cout << "Кол-во колонок pCol = " << pCol << endl; std::cout << "Кол-во строк pStr = " << pStr << endl; std::cout << "-------------------------- И Н Ф О Р М А Ц И Я о С Т О Л Б Ц А Х ------------------" << endl; unsigned optionOp = 107; // Режим int posOp = 1 ; // Позиция void *pValueOp; // Буфер для значения unsigned sizeOp = 1024; // и его размер unsigned cntOp ; // Размер считанной информации в байтах. Если это количество разделить на размер значения, // то можно получить количество считанных значений (для параметров, которые имеют массив значений). hcSqlDstInfoT Kol = { 0 };// Структура Информация о колонке результата for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, i, &Kol, sizeof(Kol), &cntOp);// Получить информацию об операторе std::cout << "...............столбик № " << i << " ......................................" << endl; std::cout << "Порядковый номер алиаса aliasno = " << Kol.aliasno << endl; std::cout << "Номер поля в таблице fieldno = " << Kol.fieldno << endl; std::cout << "Тип выражения, константа HSCLI_ET_??? type = " << Kol.type << endl; std::cout << "Длина поля в байтах len = " << Kol.len << endl; std::cout << "Смещение поля относительно начала логической записи off = " << Kol.off << endl; std::cout << "Имя кодификатора.только для coder(MYCODER, code). coder = " << Kol.coder << endl; std::cout << "Имя поля в таблице, fname = " << Kol.fname << endl; std::cout << "Формат выражения CURS_OUTEXPR func = " << Kol.func << endl; std::cout << "Переименование поля, asname = " << Kol.asname << endl; std::cout << "Ключевитость поля, key = " << Kol.key << endl; std::cout << "Сквозной номер поля в результате resno = " << Kol.resno << endl; std::cout << "................................................................." << endl; } std::cout << "-----------------------------------------------------------------" << endl; std::cout << "код ошибки при получении информации об операторе " << err << endl; std::cout << "размер sizeof(Kol) = " << sizeof(Kol) << endl; std::cout << "кол-во байтов записаных в буфер Оператора cntOp = " << cntOp << endl; std::cout << "размер sizeof(hcSqlDstInfoT) = " << cntOp << endl; std::cout << "cntOp / sizeof(hcSqlDstInfoT) = " << cntOp / sizeof(hcSqlDstInfoT) << endl; std::cout << "-----------------------------------------------------------------" << endl; std::cout << "Вывод результата запроса select * from TAB; (в таблице 4строки 2столбца)" << endl; std::cout << "------------------------------------------------------------------------" << endl; //------------------------------- Ч Т Е Н И Е Р Е З У Л Ь Т А Т О В ---------------------------- unsigned pRecSize = 0;// Адрес слова, в которое запишется размер читаемой записи в байтах. hcSqlOpenResults(pOper, &pRecSize);// Открытие результатов для чтения long gStart = 0; // С какой записи начинаем читать unique_ptr<char[]> buf(new char[pRecSize]); unsigned cnt = 0; // Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. for ( ; gStart < pStr; gStart++) { hcSqlReadResults(pOper, gStart, buf.get(), pRecSize, &cnt); // Чтение результатов std::cout << buf.get() << endl;// } //----------------------------------------------------------------------------------------------- std::cout << "------------------------------------------------------------------------" << endl; hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы std::system("pause"); } //HSCLI_ET_CHAR 0 Символьная строка //HSCLI_ET_ARRA 1 Массив байт //HSCLI_ET_BYTE 2 8 - битовое целое без знака //HSCLI_ET_INTR 3 16 - битное целое со знаком //HSCLI_ET_WORD 4 16 - битное целое без знака //HSCLI_ET_DATE 5 Дата в формате HyTech //HSCLI_ET_NMBR 6 24 - битное целое без знака //HSCLI_ET_LONG 7 32 - битное со знаком //HSCLI_ET_DWRD 8 32 - битное без знака //HSCLI_ET_FLOA 9 4 - байтовое плавающее //HSCLI_ET_CURR 10 Деньги(8 - байтовое плавающее число) //HSCLI_ET_DFLT 11 8 - байтовое плавающее //HSCLI_ET_QINT 12 64 - битное со знаком //HSCLI_ET_QWRD 13 64 - битное без знака помоему это уже намного ближе к телу , теперьбы понять почему в инфе по столбцам одни нули , хотя HSCLI_ET_CHAR 0 Символьная строка выхлоп Прикреплённая картинка
Добавлено Цитата Олег М @ hcSqlDstInfoT Kol = { sizeof(Kol) };// Структура Информация о колонке результата Это что? Должно быть hcSqlDstInfoT Kol = {0} Цитата kms @ Сегодня, 07:48 hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, &Kol, sizeof(Kol), &cntOp);// Получить информацию об операторе Ты там ниже выводишь код ошибки от предыдущей операции, надо сделать err = hcSqlGetStmtAttr...... исправил Добавлено Не не подтвердилась догадка что type HSCLI_ET_CHAR 0 Символьная строка потому что в запросе указал другую таблицу с типом данных dword а показывает все равно 0 |
Сообщ.
#54
,
|
|
|
Цитата kms @ Ты там ниже выводишь код ошибки от предыдущей операции, надо сделать err = hcSqlGetStmtAttr...... исправил Не вижу. Добавлено У тебя hcSqlGetStmtAttr возвращает какую то ошибку, потому что cntOp здесь должен был вернутся равным sizeof(Kol), т.е. 128. Сделай err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, i, &Kol, sizeof(Kol), &cntOp);// Получить информацию об операторе |
Сообщ.
#55
,
|
|
|
да точно
Код ошибки -93 — Маленький буфер Для информации выделен слишком маленький буфер. Добавлено Вот нашел , эта ошибка тянется еще с unsigned optionAttr = 101; // Режим int pos = 1; // Позиция Некоторые параметры могут представлять собой массив значений. Параметр pos определяет, какую порцию значений прикладная программа хочет прочитать. void *pValAttr=NULL;//Адрес буфера памяти, в которую будут записаны значение (значения) параметра соединения. unsigned sizeAttr = 1024;// и его размер unsigned cntAttr; // сколько байтов записали в буфер err = hcSqlGetConnectAttr(pdb, optionAttr, pos, pValAttr, sizeAttr, &cntAttr);// Получить информацию о соединении код ошибки -64 — Неправильный операнд При выполнении операции обнаружено, что операнд иммет неправильный тип или неправильное значение |
Сообщ.
#56
,
|
|
|
т.е. еще на этапе соединения какая то переменная из
hcSqlGetConnectAttr(pdb, optionAttr, pos, pValAttr, sizeAttr, &cntAttr); неправильно объявлена или какой то косяк |
Сообщ.
#57
,
|
|
|
код ошибки -64 — Неправильный операнд
эту ошибку справил hcSqlAliasInfoT bufAttr = {0}; unsigned cntAttr; err = hcSqlGetConnectAttr(pdb, HSCLI_CONN_SRV_VERS, 3, &bufAttr, sizeof(bufAttr), &cntAttr);// Получить информацию о соединении |
Сообщ.
#58
,
|
|
|
Цитата kms @ код ошибки -64 — Неправильный операнд эту ошибку справил Нет, не исправил. Догадался правильно, что проблема была в том, что ты передавал null в качестве указателя на буфер, и левый размер буфера. Только для HSCLI_CONN_SRV_VERS надо туда указатель на double передавать. А для 101, HSCLI_CONN_SRV_PATH - char buf[MAXPATH]. Кстати, зачем они тебе вообще понадобились? Цитата Олег М @ да точно Код ошибки -93 — Маленький буфер Для информации выделен слишком маленький буфер. Сделай-ка (только повнимательнее) unsigned cntOp = 0; hcSqlAliasInfoT cols[100] = {0}; err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, cols, sizeof(cols), &cntOp); И посмотри, что возвращается в err и cntOp. |
Сообщ.
#59
,
|
|
|
извиняюь , за долгую задержку , праздники.
Цитата Олег М @ Только для HSCLI_CONN_SRV_VERS надо туда указатель на double передавать. А для 101, HSCLI_CONN_SRV_PATH - char buf[MAXPATH]. Кстати, зачем они тебе вообще понадобились? Исправил , но что то всеравно версия сервера показывает 0, хотя сколько байтов записали в буфер показывает 8, я пока не стал на это заморачиватся . Цитата Олег М @ Сделай-ка (только повнимательнее) unsigned cntOp = 0; hcSqlAliasInfoT cols[100] = {0}; err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, cols, sizeof(cols), &cntOp); И посмотри, что возвращается в err и cntOp. сделал , но ошибка осталась таже самая err=-93 , cntAttr=0 |
Сообщ.
#60
,
|
|
|
А вот пробую эту функцию на вывод других параметров , например делаю так
std::cout << "********************* Определяем тип результата **********************" << endl; int typeRes = -5 ; err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_SAB_TYPE, 0, &typeRes, sizeof(typeRes), &cntOp ); std::cout << "вызываем ф-цию hcSqlGetStmtAttr c параметром HSCLI_STMT_SAB_TYPE = " << err << endl; std::cout << "Размер считанной информации в байтахcntOp = " << cntOp << endl; std::cout << "тип результата typeRes = " << typeRes << endl; std::cout << "*************************************************************************" << endl; результат ********************* Определяем тип результата ********************** вызываем ф-цию hcSqlGetStmtAttr c параметром HSCLI_STMT_SAB_TYPE = 0 Размер считанной информации в байтахcntOp = 4 тип результата typeRes = 0 ************************************************************************* |
Сообщ.
#61
,
|
|
|
а вот уже с таким параметром ,
std::cout << "********************Определяем количество алиасов**********************" << endl; int kolAlias = 0; err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_ALS_CNT, 0, &kolAlias, sizeof(kolAlias), &cntOp); std::cout << "вызываем ф-цию c параметром HSCLI_STMT_ALS_CNT = " << err << endl; std::cout << "сколько записали = " << cntOp << endl; std::cout << "количество алиасов kolAlias = " <<kolAlias<< endl; std::cout << "***********************************************************************" << endl; std::cout << "********************Определяем информацию об алиасах**********************" << endl; hcSqlAliasInfoT *pMasAl = new hcSqlAliasInfoT[kolAlias]; // Выделение памяти для массива структур алиасов err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_ALS_INFO, 0, pMasAl, sizeof(pMasAl), &cntOp); std::cout << "вызываем ф-цию c параметром HSCLI_STMT_ALS_INFO = " << err << endl; for (int i = 0; i <= kolAlias; i++) { std::cout << "HyTech-обработчик таблицы = " << pMasAl[i].hthandle << endl; std::cout << "Короткое имя таблицы = " << pMasAl[i].tname << endl; std::cout << "Синоним имени таблицы, указанный в самом SQL-запросе. = " << pMasAl[i].aname << endl; } std::cout << "***********************************************************************" << endl; результат ********************Определяем количество алиасов********************** вызываем ф-цию c параметром HSCLI_STMT_ALS_CNT = 0 сколько записали = 4 количество алиасов kolAlias = 0 *********************************************************************** ********************Определяем информацию об алиасах********************** вызываем ф-цию c параметром HSCLI_STMT_ALS_INFO = 0 HyTech-обработчик таблицы = -33686019 Короткое имя таблицы = Синоним имени таблицы, указанный в самом SQL-запросе. = ЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭе*я¶ЭЭ *********************************************************************** |
Сообщ.
#62
,
|
|
|
Цитата kms @ hcSqlAliasInfoT *pMasAl = new hcSqlAliasInfoT[kolAlias]; // Выделение памяти для массива структур алиасов err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_ALS_INFO, 0, pMasAl, sizeof(pMasAl), &cntOp); Здесь не sizeof(pMasAl) надо указывает а kolAlias, либо kolAlias * sizeof(hcSqlAliasInfoT). sizeof(pMasAl) - это размер указателя, всегда 4 или 8 байт. Добавлено Цитата kms @ unsigned cntOp = 0; hcSqlAliasInfoT cols[100] = {0}; err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, cols, sizeof(cols), &cntOp); И посмотри, что возвращается в err и cntOp. сделал , но ошибка осталась таже самая err=-93 , cntAttr=0 Покажи, как ты сделал |
Сообщ.
#63
,
|
|
|
Цитата Олег М @ Здесь не sizeof(pMasAl) надо указывает а kolAlias, либо kolAlias * sizeof(hcSqlAliasInfoT). ОК сделал, результат ********************Определяем количество алиасов********************** вызываем ф-цию c параметром HSCLI_STMT_ALS_CNT = 0 сколько записали = 4 количество алиасов kolAlias = 0 *********************************************************************** ********************Определяем информацию об алиасах********************** вызываем ф-цию c параметром HSCLI_STMT_ALS_INFO = 0 HyTech-обработчик таблицы = -33686019 Короткое имя таблицы = Синоним имени таблицы, указанный в самом SQL-запросе. = ЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭ'♀N_ЭЭ *********************************************************************** Добавлено Цитата Олег М @ Покажи, как ты сделал std::cout << "*************** ИНФОРМАЦИЯ о СТОЛБЦАХ ***********************" << endl; hcSqlDstInfoT *Kol = new hcSqlDstInfoT[pCol];// Структура Информация о колонке результата for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, Kol, 111024 , &cntOp);// Получить информацию об операторе std::cout << "ф-ция hcSqlGetStmtAttr с параметром HSCLI_STMT_DST_INFO = " << err << endl; std::cout << "Размер считанной информации в байтах. cntOp = " << cntOp << endl; std::cout << "Размер структуры sizeof(Kol) = " << sizeof(Kol[i]) << endl; std::cout << "...............столбик № " << i+1 << " ......................................" << endl; std::cout << "Порядковый номер алиаса aliasno = " << Kol[i].aliasno << endl; std::cout << "Номер поля в таблице fieldno = " << Kol[i].fieldno << endl; std::cout << "Тип выражения, константа HSCLI_ET_??? type = " << Kol[i].type << endl; std::cout << "Длина поля в байтах len = " << Kol[i].len << endl; std::cout << "Смещение поля относительно начала логической записи off = " << Kol[i].off << endl; std::cout << "Имя кодификатора.только для coder(MYCODER, code). coder = " << Kol[i].coder << endl; std::cout << "Имя поля в таблице, fname = " << Kol[i].fname << endl; std::cout << "Формат выражения CURS_OUTEXPR func = " << Kol[i].func << endl; std::cout << "Переименование поля, asname = " << Kol[i].asname << endl; std::cout << "Ключевитость поля, key = " << Kol[i].key << endl; std::cout << "Сквозной номер поля в результате resno = " << Kol[i].resno << endl; std::cout << "................................................................." << endl; } std::cout << "***********************************************************************" << endl; результат *************** ИНФОРМАЦИЯ о СТОЛБЦАХ *********************** ф-ция hcSqlGetStmtAttr с параметром HSCLI_STMT_DST_INFO = -93 Размер считанной информации в байтах. cntOp = 4 Размер структуры sizeof(Kol) = 128 ...............столбик № 1 ...................................... Порядковый номер алиаса aliasno = -842150451 Номер поля в таблице fieldno = -842150451 Тип выражения, константа HSCLI_ET_??? type = -842150451 Длина поля в байтах len = 3452816845 Смещение поля относительно начала логической записи off = 3452816845 Имя кодификатора.только для coder(MYCODER, code). coder = НННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН НННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН ННННННННННННННээээ Имя поля в таблице, fname = НННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН ННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННээээ Формат выражения CURS_OUTEXPR func = -842150451 Переименование поля, asname = НННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН ННННННННННННННННННННННННННННННННННННННННННННННННННННННННННээээ Ключевитость поля, key = -842150451 Сквозной номер поля в результате resno = -842150451 ................................................................. ф-ция hcSqlGetStmtAttr с параметром HSCLI_STMT_DST_INFO = -93 Размер считанной информации в байтах. cntOp = 4 Размер структуры sizeof(Kol) = 128 ...............столбик № 2 ...................................... Порядковый номер алиаса aliasno = -842150451 Номер поля в таблице fieldno = -842150451 Тип выражения, константа HSCLI_ET_??? type = -842150451 Длина поля в байтах len = 3452816845 Смещение поля относительно начала логической записи off = 3452816845 Имя кодификатора.только для coder(MYCODER, code). coder = НННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН ННННННННННННННННННННННННННээээ Имя поля в таблице, fname = ННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННээээ Формат выражения CURS_OUTEXPR func = -842150451 Переименование поля, asname = ННННННННННННННННННННННННННННННННННННННННээээ Ключевитость поля, key = -842150451 Сквозной номер поля в результате resno = -842150451 ................................................................. *********************************************************************** |
Сообщ.
#64
,
|
|
|
Цитата kms @ ОК сделал, результат Ты бы не результат показывал, а что именно ты сделал. Обычно у тебя там что-то ещё менее предсказуемое, чем результат Добавлено Цитата kms @ err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, Kol, 111024 , &cntOp);// Получить информацию об операторе Совсем не похоже на то, что я тебе говорил сделать. Ну да ладно. Покажи что ты до этого делаешь, весь код |
Сообщ.
#65
,
|
|
|
Скрытый текст #define HYCFG_WIN32 #include "hscli.h" #include <iostream> #include <memory> using namespace std; int main() { setlocale(LC_ALL, "RUS"); // рус локаль hcERR err; hcSqlParmT Init = { sizeof(Init) }; //// Адрес структуры с параметрами инициализации if(err=hcSqlInit(&Init) != 0 ) {/* Инициализация клиентской части */ printf("Ошибка с параметрами инициализации \n"); return 0; } std::cout << "ф-ция ""Инициализация клиентской части"" = " << err << endl; if( hcSqlCheckInit() < 0 ) { /* Проверка завершения инициализации */ printf("Ошибка завершения инициализации \n"); return 0; } std::cout << "ф-ция Проверка завершения инициализации = " << err << endl; hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. err = hcSqlAllocConnect(&pdb); // Создать соединение std::cout << "ф-ция Создать соединение = " << err << endl; // HSCLI_CONN_SRV_VERS надо туда указатель на double передавать. //А для HSCLI_CONN_SRV_PATH - char buf[MAXPATH]. //struct hcSqlAliasInfoT //{ // int hthandle; // char tname[32]; // char aname[32]; //} hcSqlAliasInfoT; /* Получить информацию об соединении */ // HSCLI_CONN_SRV_PATH 101 /* строка соединения (char[]) */ // HSCLI_CONN_SRV_VERS 102 /* Версия сервера (double) */ // HSCLI_CONN_SRV_VERS2 103 /* Версия сервера (char[]) */ // HSCLI_CONN_USER_INFO 151 /* Информация пользователя (long) */ // HSCLI_CONN_LCLADDR 152 /* Адрес (клиента) (char[]) */ // HSCLI_CONN_RMTADDR 153 /* Адрес (сервера) (char[]) */ // unsigned optionAttr = 101; // Режим // int pos = 1; // Позиция Некоторые параметры могут представлять собой массив значений. Параметр pos определяет, какую порцию значений прикладная программа хочет прочитать. // hcSqlAliasInfoT bufAttr = {0};// Адрес буфера памяти, в которую будут записаны значение(значения) параметра соединения. double bufAttr = 0; ////unsigned sizeAttr = 1024;// и его размер unsigned cntAttr=0; // сколько байтов записали в буфер err = hcSqlGetConnectAttr(pdb, HSCLI_CONN_SRV_VERS, 0, &bufAttr, sizeof(bufAttr), &cntAttr);// Получить информацию о соединении std::cout << "ф-ция Получить информацию о соединении err = " << err << endl; std::cout << "сколько байтов записали в буфер cntAttr = " << cntAttr << endl ; std::cout << "bufAttr = " << bufAttr << endl ; // for (int i = 0; i < 32; ++i) printf("%d \n", bufAttr ); // std::cout << "bufAttr.aname = " << bufAttr.aname << endl; //// for (int i = 0; i < 32; ++i) // printf("%d \n", bufAttr.tname ); // std::cout << "bufAttr.tname = " << bufAttr.tname << endl; std::cout << "------------------------------------------------------------------------" << endl; err = hcSqlConnect(pdb, "tcpip:/localhost:13000", "HTADMIN", "PASSWORD");//Установить связь с СУБД std::cout << "ф-ия Установить связь с СУБД = " << err << endl; hcHSTMT pOper;// Адрес памяти, куда будет записан идентификатор оператора. hcSqlAllocStmt(pdb, &pOper); // Создать оператор hcSqlExecDirect(pOper, "fix all; select * from TAB;");// TAB TABLES USERSPEC UGROUPS int pCol = 0; // Место для количества колонок hcRECNO pStr = 0; // Место для количества строк hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата hcSqlRowCount(pOper, &pStr); // Получить количество строк результата std::cout << "Кол-во колонок pCol = " << pCol << endl; std::cout << "Кол-во строк pStr = " << pStr << endl; //unsigned optionOp = 107; // Режим //int posOp = 1 ; // Позиция //void *pValueOp; // Буфер для значения //unsigned sizeOp = 1111024; // и его размер unsigned cntOp = 0 ; // Размер считанной информации в байтах. Если это количество разделить на размер значения, // то можно получить количество считанных значений (для параметров, которые имеют массив значений). std::cout << "********************* Определяем тип результата **********************" << endl; int typeRes = -5 ; err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_SAB_TYPE, 0, &typeRes, sizeof(typeRes), &cntOp ); std::cout << "вызываем ф-цию hcSqlGetStmtAttr c параметром HSCLI_STMT_SAB_TYPE = " << err << endl; std::cout << "Размер считанной информации в байтах cntOp = " << cntOp << endl; std::cout << "тип результата typeRes = " << typeRes << endl; std::cout << "*************************************************************************" << endl; std::cout << "********************* Определяем количество hytech-обработчиков *******" << endl; cntOp = 0; int bufObr[100]; // err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_SAB_HNDCNT, 0, &bufObr, sizeof(bufObr), &cntOp); // получим количество обработчиков std::cout << "вызываем ф-цию c параметром HSCLI_STMT_SAB_HNDCNT = " << err << endl;// здесь надо обработать ошибку std::cout << "количество записанных байт cntOp = " << cntOp << endl; for (int i = 0; i <= cntOp; i++) { int h=0; err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_SAB_HANDLES, i, &h, sizeof(h), 0);// получаем очередной обработчик std::cout << "вызываем ф-цию c параметром HSCLI_STMT_SAB_HANDLES = " << err << endl; std::cout << "номер обработчика h = " << h << endl; } std::cout << "***********************************************************************" << endl; std::cout << "********************Определяем количество алиасов**********************" << endl; int kolAlias = 0; err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_ALS_CNT, 0, &kolAlias, sizeof(kolAlias), &cntOp); std::cout << "вызываем ф-цию c параметром HSCLI_STMT_ALS_CNT = " << err << endl; std::cout << "сколько записали = " << cntOp << endl; std::cout << "количество алиасов kolAlias = " <<kolAlias<< endl; std::cout << "***********************************************************************" << endl; std::cout << "********************Определяем информацию об алиасах**********************" << endl; hcSqlAliasInfoT *pMasAl = new hcSqlAliasInfoT[kolAlias]; // Выделение памяти для массива структур алиасов err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_ALS_INFO, 0, pMasAl, kolAlias * sizeof(hcSqlAliasInfoT), &cntOp); std::cout << "вызываем ф-цию c параметром HSCLI_STMT_ALS_INFO = " << err << endl; for (int i = 0; i <= kolAlias; i++) { std::cout << "HyTech-обработчик таблицы = " << pMasAl[i].hthandle << endl; std::cout << "Короткое имя таблицы = " << pMasAl[i].tname << endl; std::cout << "Синоним имени таблицы, указанный в самом SQL-запросе. = " << pMasAl[i].aname << endl; } std::cout << "***********************************************************************" << endl; std::cout << "******************** Определяем тип возращаемого значеия RC **********" << endl; int typeRC = -5; // тип возвращаемого значения err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_RC_TYPE, 0, &typeRC, sizeof(typeRC), &cntOp); std::cout << "вызываем ф-цию c параметром HSCLI_STMT_ALS_CNT = " << err << endl; std::cout << "сколько записали = " << cntOp << endl; std::cout << " тип typeRC = " << typeRC << endl; std::cout << "***********************************************************************" << endl; std::cout << "*************** ИНФОРМАЦИЯ о СТОЛБЦАХ ***********************" << endl; hcSqlDstInfoT *Kol = new hcSqlDstInfoT[pCol];// Структура Информация о колонке результата std::cout << "размер sizeof(Kol) = " << sizeof(Kol) << endl; std::cout << "Размер считанной информации в байтах. cntOp = " << cntOp << endl; std::cout << "cntOp / sizeof(hcSqlDstInfoT) = " << cntOp / sizeof(hcSqlDstInfoT) << endl; for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, Kol, 111024 , &cntOp);// Получить информацию об операторе std::cout << "ф-ция hcSqlGetStmtAttr с параметром HSCLI_STMT_DST_INFO = " << err << endl; std::cout << "...............столбик № " << i+1 << " ......................................" << endl; std::cout << "Порядковый номер алиаса aliasno = " << Kol[i].aliasno << endl; std::cout << "Номер поля в таблице fieldno = " << Kol[i].fieldno << endl; std::cout << "Тип выражения, константа HSCLI_ET_??? type = " << Kol[i].type << endl; std::cout << "Длина поля в байтах len = " << Kol[i].len << endl; std::cout << "Смещение поля относительно начала логической записи off = " << Kol[i].off << endl; std::cout << "Имя кодификатора.только для coder(MYCODER, code). coder = " << Kol[i].coder << endl; std::cout << "Имя поля в таблице, fname = " << Kol[i].fname << endl; std::cout << "Формат выражения CURS_OUTEXPR func = " << Kol[i].func << endl; std::cout << "Переименование поля, asname = " << Kol[i].asname << endl; std::cout << "Ключевитость поля, key = " << Kol[i].key << endl; std::cout << "Сквозной номер поля в результате resno = " << Kol[i].resno << endl; std::cout << "................................................................." << endl; } std::cout << "***********************************************************************" << endl; std::cout << "********** Ч Т Е Н И Е Р Е З У Л Ь Т А Т О В *******************" << endl; unsigned pRecSize = 0;// Размер читаемой записи в байтах. hcSqlOpenResults(pOper, &pRecSize);// Открытие результатов для чтения std::cout << "вызываем ф-цию hcSqlOpenResults = " << err << endl; std::cout << "размер читаемой записи в байтах. pRecSize = " << pRecSize<< endl; unique_ptr<char[]> buf(new char[pRecSize]); unsigned cnt = 0; // количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. for (long gStart = 0; gStart < pStr; gStart++) { // std::cout << " количество считанных записей cnt / pRecSize = " << cnt / pRecSize << endl; std::cout << " количество байтов данных, помещённых в буфер пользователя cnt = " << cnt << endl; hcSqlReadResults(pOper, gStart, buf.get(), pRecSize, &cnt); // Чтение результатов std::cout << buf.get() << endl;// } std::cout << "***********************************************************************" << endl; hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы std::system("pause"); } Добавлено Цитата Олег М @ Цитата kms @ Сегодня, 10:22 err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, 0, Kol, 111024 , &cntOp);// Получить информацию об операторе Совсем не похоже на то, что я тебе говорил сделать. Ну да ладно. Покажи что ты до этого делаешь, весь код Да тут я забыл вернуть , kolAlias * sizeof(hcSqlAliasInfoT) , пробывал подставлял туда уже и просто цыфры всякие |
Сообщ.
#66
,
|
|
|
Цитата kms @ err = hcSqlGetStmtAttr(pdb, HSCLI_STMT_DST_INFO, Здесь надо, похоже, pOper передавать - hcSqlGetStmtAttr(pOper, |
Сообщ.
#67
,
|
|
|
Цитата Олег М @ Здесь надо, похоже, pOper передавать - hcSqlGetStmtAttr(pOper, Да точно , как я так прозевал, сейчас во всех вызовах ф-ции hcSqlGetStmtAttr заменил pdb на pOper. но ошибка серавно таже -93 Маленький буфер на данный момент std::cout << "*************** ИНФОРМАЦИЯ о СТОЛБЦАХ ***********************" << endl; hcSqlDstInfoT *Kol = new hcSqlDstInfoT[pCol];// Структура Информация о колонке результата std::cout << "размер sizeof(Kol) = " << sizeof(Kol) << endl; std::cout << "Размер считанной информации в байтах. cntOp = " << cntOp << endl; std::cout << "cntOp / sizeof(hcSqlDstInfoT) = " << cntOp / sizeof(hcSqlDstInfoT) << endl; for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, Kol, sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе std::cout << "ф-ция hcSqlGetStmtAttr с параметром HSCLI_STMT_DST_INFO = " << err << endl; std::cout << "...............столбик № " << i + 1 << " ......................................" << endl; std::cout << "Порядковый номер алиаса aliasno = " << Kol[i].aliasno << endl; std::cout << "Номер поля в таблице fieldno = " << Kol[i].fieldno << endl; std::cout << "Тип выражения, константа HSCLI_ET_??? type = " << Kol[i].type << endl; std::cout << "Длина поля в байтах len = " << Kol[i].len << endl; std::cout << "Смещение поля относительно начала логической записи off = " << Kol[i].off << endl; std::cout << "Имя кодификатора.только для coder(MYCODER, code). coder = " << Kol[i].coder << endl; std::cout << "Имя поля в таблице, fname = " << Kol[i].fname << endl; std::cout << "Формат выражения CURS_OUTEXPR func = " << Kol[i].func << endl; std::cout << "Переименование поля, asname = " << Kol[i].asname << endl; std::cout << "Ключевитость поля, key = " << Kol[i].key << endl; std::cout << "Сквозной номер поля в результате resno = " << Kol[i].resno << endl; std::cout << "................................................................." << endl; } std::cout << "***********************************************************************" << endl; Добавлено вот чето пошло , сделал так err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, Kol, 100 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе т.е. поставил на угад 100 , сейчас ошибки нету, уже легче Добавлено результат *************** ИНФОРМАЦИЯ о СТОЛБЦАХ *********************** размер sizeof(Kol) = 4 Размер считанной информации в байтах. cntOp = 0 cntOp / sizeof(hcSqlDstInfoT) = 0 ф-ция hcSqlGetStmtAttr с параметром HSCLI_STMT_DST_INFO = 0 ...............столбик № 1 ...................................... Порядковый номер алиаса aliasno = 0 Номер поля в таблице fieldno = 1 Тип выражения, константа HSCLI_ET_??? type = 4 Длина поля в байтах len = 2 Смещение поля относительно начала логической записи off = 0 Имя кодификатора.только для coder(MYCODER, code). coder = Имя поля в таблице, fname = Формат выражения CURS_OUTEXPR func = 2 Переименование поля, asname = Ключевитость поля, key = -1 Сквозной номер поля в результате resno = -1 ................................................................. ф-ция hcSqlGetStmtAttr с параметром HSCLI_STMT_DST_INFO = 0 ...............столбик № 2 ...................................... Порядковый номер алиаса aliasno = 0 Номер поля в таблице fieldno = 2 Тип выражения, константа HSCLI_ET_??? type = 11 Длина поля в байтах len = 8 Смещение поля относительно начала логической записи off = 2 Имя кодификатора.только для coder(MYCODER, code). coder = Имя поля в таблице, fname = Формат выражения CURS_OUTEXPR func = 2 Переименование поля, asname = Ключевитость поля, key = -1 Сквозной номер поля в результате resno = -1 ................................................................. *********************************************************************** в запросе сейчас таблица на 2колонки 1строка по описанию таблицы тип 1-го поля - unsigned short 2-го поля - double вот и как раз судя по выводу это как раз и есть то что надо , т.е. Тип выражения, константа HSCLI_ET_??? type = возвращает правильный результат теперь думаю как это красиво применить |
Сообщ.
#68
,
|
|
|
Что возвращается в cntOp?
|
Сообщ.
#69
,
|
|
|
может быть как то так ,
unsigned pRecSize = 0;// Размер читаемой записи в байтах. err = hcSqlOpenResults(pOper, &pRecSize);// Открытие результатов для чтения for (long gStart = 0; gStart < pStr; gStart++) { for(int j = 0; j < pCol; j++) { // перебираем столбики как то надо брать Kol[j].len - Длина поля в байтах из pRecSize hcSqlReadResults(pOper, gStart, buf.get(), pRecSize, &cnt); // Чтение результатов std::cout << buf.get() << endl; } } как это выразить в коде не могу сообразить Добавлено Цитата Олег М @ Что возвращается в cntOp? Размер считанной информации в байтах. cntOp = 256 |
Сообщ.
#70
,
|
|
|
Цитата Олег М @ for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков Это убирай. Там функция за раз возвращает информацию по всем столбцам Добавлено Цитата kms @ rr = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, Kol, 100 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе Здесь сделай pCol * sizeof(hcSqlAliasInfoT). (Должно быть тоже 256) |
Сообщ.
#71
,
|
|
|
Цитата Олег М @ Это убирай. Там функция за раз возвращает информацию по всем столбцам понял Цитата Олег М @ Здесь сделай pCol * sizeof(hcSqlAliasInfoT). (Должно быть тоже 256) сделал но опять ошибка -93 Добавлено хватает даже вот так 4 * sizeof(hcSqlAliasInfoT) |
Сообщ.
#72
,
|
|
|
Дальше пробегись по всем строкам
Цитата Олег М @ char buf[1024] unsigned cnt = 0; for (hcRECNO rec = 0;; ++rec) { const auto res = hcSqlReadResults(hOper, rec, buf, sizeof(buf), &cnt); if (res != 0 || cnt == 0) break; char *p = buf; for (size_t i = 0; i < cntOp / sizeof(hcSqlAliasInfoT); ++i) { switch(Kol[i].type) { case HSCLI_ET_CHAR: std::cout << "HSCLI_ET_CHAR, " << std::string(p, Kol[i].len) << std::endl; case HSCLI_ET_INTR: std::cout << "HSCLI_ET_INTR, " << *reinterpert_cast<int16_t *>(p) << std::endl; ..... } p += Kol[i].len; } } |
Сообщ.
#73
,
|
|
|
че то ошибка на вот этой строке
case HSCLI_ET_WORD: cout << "HSCLI_ET_WORD, " << string(p, Kol[i].len) << endl; ругается на << СерьезностьКодОписаниеПроектФайлСтрока ОшибкаC2679бинарный "<<": не найден оператор, принимающий правый операнд типа "std::basic_string<char,std::char_traits<char>,std::allocator<char>>" (или приемлемое преобразование отсутствует)AdmHyTechc:\users\admin\desktop\admhytech\admhytech\main.cpp178 |
Сообщ.
#74
,
|
|
|
Забыл break добавить
switch(Kol[i].type) { case HSCLI_ET_CHAR: { std::string s(p, Kol[i].len); std::cout << "HSCLI_ET_CHAR, " << s.c_str() << std::endl; } break; case HSCLI_ET_INTR: std::cout << "HSCLI_ET_INTR, " << *reinterpert_cast<int16_t *>(p) << std::endl; break; Добавлено Цитата kms @ case HSCLI_ET_WORD: cout << "HSCLI_ET_WORD, " << string(p, Kol[i].len) << endl; case HSCLI_ET_WORD: std::cout << "HSCLI_ET_INTR, " << *reinterpert_cast<uint16_t *>(p) << std::endl; break; Добавлено Для каждой константы надо своё преобразование делать. Не копируй Добавлено HSCLI_ET_DFLT: std::cout << "HSCLI_ET_INTR, " << *reinterpert_cast<double *>(p) << std::endl; break; |
Сообщ.
#75
,
|
|
|
Цитата Олег М @ for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков Это убирай. Там функция за раз возвращает информацию по всем столбцам не а , попробывал убрать , и не получается , из описания функции 3 параметр как раз про это вот и надо по нему пройти hcSqlGetStmtAttr — Получить информацию об операторе Назначение Функция hcSqlGetStmtAttr возвращает прикладной программе указанную информацию о операторе. Прототип hcERR hcSqlGetStmtAttr( hcHSTMT h, /* Идентификатор оператора */ unsigned option, /* Режим */ int pos, /* Позиция */ void *pValue, /* Буфер для значения */ unsigned size, /* и его размер */ unsigned *cnt); /* сколько байтов записали в буфер */ Параметры ТипАргументЗначение hcHDB (входной)hИдентификатор оператора, параметры которого читаем. unsigned (входной)optionИдентификатор параметра оператора, который меняем. Параметр option может принимать следующие значения: HSCLI_STMT_SAB_TYPE — Тип результата HSSQL_STMT_SAB_HNDCNT — Количество hytech-обработчиков HSSQL_STMT_SAB_HANDLES — hytech-обработчики HSCLI_STMT_ALS_CNT — Количество алиасов HSCLI_STMT_ALS_INFO — информация об алиасах HSCLI_STMT_DST_INFO — Информация об колонке результата HSCLI_STMT_RC_TYPE — Тип возвращаемого значения HSCLI_STMT_RC_SIZE — Длина возвращаемого значения в байтах HSCLI_STMT_RC_BODY — Возвращаемое значение int (входной)posНекоторые параметры оператора могут представлять собой массив значений. Параметр pos определяет, какую порцию значений прикладная программа хочет прочитать. const void * (выходной)pValueАдрес буфера памяти, в которую будут записаны значение (значения) параметра оператора. unsigned (входной)sizeРазмер буфера памяти в байтах. Функция всегда записывает в буфер значение полностью, поэтому размер буфера должен быть достаточным, чтобы в него поместилось хотя бы одно значение. unsigned* (выходной)cntРазмер считанной информации в байтах. Если это количество разделить на размер значения, то можно получить количество считанных значений (для параметров, которые имеют массив значений). поетому сделал так лишний вывод поуберал оставил саму суть #define HYCFG_WIN32 #include "hscli.h" #include <iostream> #include <memory> using namespace std; int main() { setlocale(LC_ALL, "RUS"); // рус локаль hcERR err; hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации if (err = hcSqlInit(&Init) != 0) {/* Инициализация клиентской части */ printf("Ошибка с параметрами инициализации \n"); return 0; } if (hcSqlCheckInit() < 0) { /* Проверка завершения инициализации */ printf("Ошибка завершения инициализации \n"); return 0; } hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. err = hcSqlAllocConnect(&pdb); // Создать соединение double bufAttr = 0; // буфер Атрибутов unsigned cntAttr = 0; // и сколько байтов записали в этот буфер err = hcSqlGetConnectAttr(pdb, HSCLI_CONN_SRV_VERS, 0, &bufAttr, sizeof(bufAttr), &cntAttr);// Получить информацию о соединении err = hcSqlConnect(pdb, "tcpip:/localhost:13000", "HTADMIN", "PASSWORD");//Установить связь с СУБД hcHSTMT pOper;// Адрес памяти, куда будет записан идентификатор оператора. err = hcSqlAllocStmt(pdb, &pOper); // Создать оператор err = hcSqlExecDirect(pOper, "fix all; select * from TAB;");// Выполняем SQLзапрос TAB TABLES USERSPEC UGROUPS int pCol = 0; // количество колонок hcRECNO pStr = 0; // количество строк hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата hcSqlRowCount(pOper, &pStr); // Получить количество строк результата unsigned cntOp = 0; // Размер считанной информации в байтах. hcSqlDstInfoT *Kol = new hcSqlDstInfoT[pCol];// Структура Информация о колонке результата err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, Kol, 4 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе unsigned pRecSize = 0; // Размер читаемой записи в байтах. err = hcSqlOpenResults(pOper, &pRecSize);// Открытие результатов для чтения unique_ptr<char[]> buf(new char[pRecSize]); unsigned cnt = 0; // количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, Kol, 4 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе } for (long i = 0; i < pStr; i++) { std::cout << " строка " << i+1 ; const auto err = hcSqlReadResults(pOper, i, buf.get(), pRecSize, &cnt);// Чтение результатов char *p = buf.get(); for (int j = 0; j < pCol; j++) { // pRecSize switch (Kol[j].type) { case HSCLI_ET_CHAR: // 0 Массив символов длиной не более заданной { std::cout << " столбик" << j+1; // std::string s(p, Kol[i].len); // std::cout << "HSCLI_ET_CHAR, " << s.c_str(); } break; ////case HSCLI_ET_INTR: // 3 Элемент - signed short // //std::cout << "HSCLI_ET_INTR, " << *reinterpert_cast<int16_t *>(p) ; //// break; ////case HSCLI_ET_WORD: // 4 Элемент - unsigned short // //std::cout << "HSCLI_ET_WORD, " << *reinterpert_cast<uint16_t *>(p) << std::endl; //// break; ////case HSCLI_ET_DFLT: // 11 Элемент - double // //std::cout << "HSCLI_ET_DFLT, " << *reinterpert_cast<double *>(p) ; //// break; // //case // //cout << "HSCLI_ET_WORD, " << string(p, Kol[i].len) ; // //break; } p += Kol[j].len; } cout << endl ; } // HSCLI_ET_ARRA 1 /* Массив байтов заданной длины */ // HSCLI_ET_BYTE 2 /* Элемент - unsigned char (короткое целое) */ // HSCLI_ET_DATE 5 /* Дата - unsigned short */ // HSCLI_ET_NMBR 6 /* Номер - 3-х байтовое целое без знака */ // HSCLI_ET_LONG 7 /* Элемент - long int */ // HSCLI_ET_DWRD 8 /* Элемент - unsigned long int */ // HSCLI_ET_FLOA 9 /* Элемент - float */ // HSCLI_ET_CURR 10 /* Деньги (double) */ // HSCLI_ET_QINT 12 /* Элемент - signed __int64 */ // HSCLI_ET_QWRD 13 /* Элемент - unsigned __int64 */ hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы std::system("pause"); } результат строка 1 столбик1 столбик2 строка 2 столбик1 столбик2 строка 3 столбик1 столбик2 строка 4 столбик1 столбик2 Для продолжения нажмите любую клавишу . . . |
Сообщ.
#76
,
|
|
|
вообщем переделал опять ,
char bufOut[1024]; for (long i = 0; i < pStr; i++)//идем по строкам { std::cout << " строка " << i+1 ; const auto err = hcSqlReadResults(pOper, i, bufOut, sizeof(bufOut), &cnt);// Чтение результатов char *p = bufOut; for (size_t j = 0; j < cntOp / sizeof(hcSqlAliasInfoT); ++j) { switch (Kol[j].type) { case HSCLI_ET_CHAR: // 0 Массив символов длиной не более заданной { std::cout << " столбик" << j+1; std::string s(p, Kol[i].len); std::cout << "HSCLI_ET_CHAR, " << s.c_str(); } break; ////case HSCLI_ET_INTR: // 3 Элемент - signed short // //std::cout << "HSCLI_ET_INTR, " << *reinterpert_cast<int16_t *>(p) ; //// break; ////case HSCLI_ET_WORD: // 4 Элемент - unsigned short // //std::cout << "HSCLI_ET_WORD, " << *reinterpert_cast<uint16_t *>(p) << std::endl; //// break; ////case HSCLI_ET_DFLT: // 11 Элемент - double // //std::cout << "HSCLI_ET_DFLT, " << *reinterpert_cast<double *>(p) ; //// break; // //case // //cout << "HSCLI_ET_WORD, " << string(p, Kol[i].len) ; // //break; } p += Kol[j].len; } std::cout << std::endl ; } теперь на вот этой строке std::string s(p, Kol[i].len); Прикреплённая картинка
|
Сообщ.
#77
,
|
|
|
и главное консоль остается висеть , тоесть как бы не совсем падает
Прикреплённая картинка
Добавлено делаю так std::cout << " столбик" << j+1 << " "<< Kol[i].len; //std::string s(p, Kol[i].len); чтобы посмотреть че там с длиной вот выхлоп строка 1 столбик1 32 столбик2 32 строка 2 столбик1 64 столбик2 64 строка 3 столбик1 5007 столбик2 5007 строка 4 столбик1 4261281277 столбик2 4261281277 Для продолжения нажмите любую клавишу . . . |
Сообщ.
#78
,
|
||||||||||||||||||||||||||||||||||||
|
Вот что получилось вот к этой таблице делаем запрос и пытаемся все ее вывести на экран
Описание таблицы create table "GROUP" ( ID dword surrogate , NAME char(32) unique , GRP byte key , AREA word key , EXPDATE date );
вот таким кодом прохожу for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, Kol, 4 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе } char bufOut[1024]; for (long i = 0; i < pStr; i++)//идем по строкам { const auto err = hcSqlReadResults(pOper, i, bufOut, sizeof(bufOut), &cnt);// Чтение результатов char *p = bufOut; for (size_t j = 0; j < cntOp / sizeof(hcSqlAliasInfoT); ++j) { switch (Kol[j].type) { case HSCLI_ET_CHAR: // 0 Массив символов длиной не более заданной { std::string s(p, Kol[i].len); std::cout << s.c_str() << " " ; } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины break; case HSCLI_ET_BYTE: // 2 Элемент - unsigned char (короткое целое) // std::cout << *reinterpret_cast<char *>(p) << " "; break; case HSCLI_ET_INTR: // 3 Элемент - signed short std::cout << *reinterpret_cast<signed short *>(p) << " " ; break; case HSCLI_ET_WORD: // 4 Элемент - unsigned short std::cout << *reinterpret_cast<unsigned short *>(p) << " " ; break; case HSCLI_ET_DATE: // 5 Дата - unsigned short std::cout << *reinterpret_cast<unsigned short *>(p) << " " ; break; case HSCLI_ET_NMBR: //6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); break; case HSCLI_ET_LONG: //7 Элемент - long int std::cout << *reinterpret_cast<long int *>(p) << " " ; break; case HSCLI_ET_DWRD: // 8 Элемент - unsigned long int в БД это dword std::cout << *reinterpret_cast<unsigned long int *>(p) << " "; break; case HSCLI_ET_FLOA: // 9 Элемент - float std::cout << *reinterpret_cast<float *>(p) << " "; break; case HSCLI_ET_CURR: // 10 Деньги (double) std::cout << *reinterpret_cast<double *>(p) << " "; break; case HSCLI_ET_DFLT: // 11 Элемент - double std::cout << *reinterpret_cast<double *>(p) << " "; break; case HSCLI_ET_QINT: // 12 Элемент - signed __int64 std::cout << *reinterpret_cast<signed __int64 *>(p) << " "; break; case HSCLI_ET_QWRD: // 13 Элемент - unsigned __int64 std::cout << *reinterpret_cast<unsigned __int64 *>(p) << " "; break; } p += Kol[j].len; } std::cout << std::endl ; } получаю вот такой результат 1 qwea 40884 40857 2 qweasd 40884 40857 3 q 5653 0 4 cж 5653 0 5 cж 5653 40939 6 тут на 6 строке уходит в ошибку но хоть уже есть сдвиг Добавлено Ребята извините перепутал одну букву всего навсего i на j вот исправил std::string s(p, Kol[i].len); испрвил на std::string s(p, Kol[j].len); результат 1 qweasd 40884 40857 2 qweasd 40884 40857 3 qweasd 5653 0 4 cжгcжг 5653 0 5 cжгcжг 5653 40939 6 длўдлў 5653 40939 Для продолжения нажмите любую клавишу . . . один столбик не выводит и руские буквы не в той кодеровке |
Сообщ.
#79
,
|
|
|
Цитата kms @ один столбик не выводит и руские буквы не в той кодеровке Тут надо смотреть в какой кодировке строки хранятся в базе. |
Сообщ.
#80
,
|
|
|
Вот интересную вещичку сейчас ковыряю
https://habrahabr.ru/company/yandex/blog/303282/ там первая ссылка на исходники Добавлено Цитата Олег М @ Тут надо смотреть в какой кодировке строки хранятся в базе. это понятно Добавлено вооще под винду ее закомпилить |
Сообщ.
#81
,
|
|
|
на данный момент получил вот такое
Скрытый текст #define HYCFG_WIN32 #include "hscli.h" #include <iostream> #include <memory> using namespace std; int main() { setlocale(LC_ALL, "RUS"); // рус локаль hcERR err ; // Код ошибки hcHDB pdb ; // Адрес памяти, куда будет записан идентификатор соединения. hcHSTMT pOper ; // Адрес памяти, куда будет записан идентификатор оператора. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации int pCol = 0 ; // количество колонок hcRECNO pStr = 0 ; // количество строк unsigned cntOp = 0 ; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0 ; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . unsigned cntOut = 0 ; // для ф-ции "Чтение результатов" Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. if (err = hcSqlInit(&Init) != 0) {/* Инициализация клиентской части */ printf("Ошибка с параметрами инициализации \n"); return 0; } if (hcSqlCheckInit() < 0) { /* Проверка завершения инициализации */ printf("Ошибка завершения инициализации \n"); return 0; } err = hcSqlAllocConnect(&pdb); // Создать соединение err = hcSqlConnect(pdb, "tcpip:/localhost:13000", "HTADMIN", "PASSWORD");//Установить связь с СУБД err = hcSqlAllocStmt(pdb, &pOper); // Создать оператор err = hcSqlExecDirect(pOper, "fix all; select * from CITY;"); // Выполняем SQLзапрос GROUP TAB TABLES USERSPEC UGROUPS err = hcSqlNumResultCols(pOper, &pCol) ; // Получить количество колонок результата err = hcSqlRowCount(pOper, &pStr) ; // Получить количество строк результата std::cout << "pStr =" << pStr << " " << endl; hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol];// Структура "Информация о колонках результата" err = hcSqlOpenResults(pOper, &pRecSize); // Открытие результатов для чтения for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, infCol, pCol * 4 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе char bufOut[1024]; // Адрес буфера для присылаемых записей. for (long i = 0; i < pStr; i++)//идем по строкам { const auto err = hcSqlReadResults(pOper, i, bufOut, sizeof(bufOut), &cntOut);// Чтение результатов char *p = bufOut; for (int j = 0; j < pCol; j++ ) // идем по колонкам { switch (infCol[j].type) { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной std::string s(p, infCol[j].len) ; std::cout << s.c_str() << " " ; } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины std::cout << *reinterpret_cast<unsigned char *>(p) << " "; break; case HSCLI_ET_BYTE: // 2 Элемент - unsigned char (короткое целое) short std::cout << *reinterpret_cast<unsigned char *>(p) << " "; break; case HSCLI_ET_INTR: // 3 Элемент - signed short std::cout << *reinterpret_cast<signed short *>(p) << " " ; break; case HSCLI_ET_WORD: // 4 Элемент - unsigned short std::cout << *reinterpret_cast<unsigned short *>(p) << " " ; break; case HSCLI_ET_DATE: // 5 Дата - unsigned short std::cout << *reinterpret_cast<unsigned short *>(p) << " " ; break; case HSCLI_ET_NMBR: //6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); break; case HSCLI_ET_LONG: //7 Элемент - long int std::cout << *reinterpret_cast<long int *>(p) << " " ; break; case HSCLI_ET_DWRD: // 8 Элемент - unsigned long int в БД это dword std::cout << *reinterpret_cast<unsigned long int *>(p) << " "; break; case HSCLI_ET_FLOA: // 9 Элемент - float std::cout << *reinterpret_cast<float *>(p) << " "; break; case HSCLI_ET_CURR: // 10 Деньги (double) std::cout << *reinterpret_cast<double *>(p) << " "; break; case HSCLI_ET_DFLT: // 11 Элемент - double std::cout << *reinterpret_cast<double *>(p) << " "; break; case HSCLI_ET_QINT: // 12 Элемент - signed __int64 std::cout << *reinterpret_cast<signed __int64 *>(p) << " "; break; case HSCLI_ET_QWRD: // 13 Элемент - unsigned __int64 std::cout << *reinterpret_cast<unsigned __int64 *>(p) << " "; break; } p += infCol[j].len; } std::cout << std::endl ; } hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы std::system("pause"); } результат Скрытый текст 1 ?R┐бR┐R<мбЄ-- -?┐га? 0 0 2 Ў аRўбЄ 0 0 3 '< ¤ЁўRбвRЄ 0 0 4 'R<-?з-лc 0 0 5 "гЄЁ 0 0 6 ?RаЁ- 0 0 7 '-?│-лc 0 0 9 ?< ?Rў?й?-бЄ 0 0 10 ?RбЄў 0 0 11 гаЎ 0 0 12 ?.?Rў?RаR¤ 0 0 13 ??<м?R 0 0 14 ? <Ёз-лc 0 0 15 "Євга 0 0 16 га┐г<Ё 0 0 17 ??- c 0 0 18 ?.?бЁЇ?-ЄR 0 0 19 "│ ┐Єг 0 0 20 ?R-¤R- 0 0 21 аЇЁз - 0 0 22 ?Ё│-?в ┐ЎRўбЄR? 0 0 23 ?RЄвRа 0 0 24 '?ае-пп ?ЄR-м 0 0 25 ??а?§Rўлc 0 0 27 '?<ЁеЁ-R 0 0 28 ??R¤-лc 0 0 29 ?ўRаR- 0 0 30 " ЇЇл 0 0 31 ? cв?а 0 0 32 ?Rа-лc 0 0 33 'RаR-?│ 0 0 34 ?R<R¤?│-лc 0 0 35 ?R<ми п- ? ав?<м 0 0 36 ? ев?абЄ 0 0 37 ?ЁаRЎЁ¤│ - 0 0 38 "?бвЁў <м-лc 0 0 39 ?Rўлc ┐Ёа 0 0 40 ?┐?г-м 0 0 41 -Ёв 0 0 42 ' ? -аR? 0 0 43 <ЁЇ?жЄ 0 0 44 ' е <Ё- 0 0 45 ?RўRбЁЎЁабЄ 0 0 46 ' ┐ а 0 0 47 ?а?-Ўга? 0 0 48 ??┐?аRўR 0 0 49 ??<?RаR¤ 0 0 50 ?аЄгвбЄ 0 0 51 ?Ёў -м 0 0 52 ?RбвRў 0 0 53 ?<мЎ - 0 0 54 'лбRЄR?Rа- п 0 0 55 ?┐бЄ 0 0 56 ' -Ё-R 0 0 57 ?а б-R¤ а 0 0 58 ?Rўлc "а? < 0 0 59 <?-Ё-?а ¤ 0 0 60 ?┐габЄ 0 0 61 ? а- г< 0 0 62 ?габЄ 0 0 63 ? <Ё-Ё-?а ¤ 0 0 64 'ў?ам 0 0 65 <ЁвRўЄR 0 0 66 <Ё - 0 0 67 ?R<миRc ? ┐?-м 0 0 68 ? ? ¤ - 0 0 69 'R§-?б?-бЄR? 0 0 70 ??а?пб<RўЄ 0 0 71 ?ЁЄR< ?ўбЄ-- -?┐га? 0 0 72 "ббгаЁcбЄ 0 0 73 ?га┐ -бЄ 0 0 74 -??¤R┐л- 0 0 75 ?а вбЄ 0 0 76 ?Ё│-Ё? <Ўл 0 0 77 'RзЁ 0 0 78 ? § -м 0 0 79 'Rў. ? ў -м 0 0 80 ?. ? ав?<м 0 0 81 ?а б-RпабЄ 0 0 82 ?Rаб ЄRў 0 0 83 ?│-R-' е <Ё-бЄ 0 0 84 ?RўRаRббЁcбЄ 0 0 85 ?пвЁ?RабЄ 0 0 86 'ў?а¤<RўбЄ 0 0 87 ?л§л< 0 0 88 ??а┐м 0 0 89 ? еR¤Є 0 0 90 ?га?п 0 0 91 ?габЄR? 0 0 92 ' -Єв-??в?аЎга? 0 0 93 ? <г│бЄ п RЎ< бвм 0 0 94 ?-? абЄ 0 0 95 'л§а -м 0 0 96 '< ¤Ё┐Ёа 0 0 97 ? cзЁеЁ-б 0 0 98 'Rж?RаR¤RЄ 0 0 99 ??-§ 0 0 100 ??ваRЇ ў<RўбЄ-? ┐з вбЄЁc 0 0 101 ? cбЄЁc 0 0 102 :cбЄ 0 0 103 'г< 0 0 104 ?ас< 0 0 105 :Є в?аЁ-Ўга? 0 0 106 Ї."?-? бваЁ 0 0 107 "<мп-RўбЄ 0 0 108 б.?R?RаR¤бЄR? 0 0 109 ?RўRЁ<мЁ-RўЄ 0 0 110 ?R¤R<мбЄ 0 0 111 ?R<R-м 0 0 112 ?ЄвпЎамбЄЁc 0 0 113 ' а вRў 0 0 114 "?-? бваЁ 0 0 115 ?R<?- 0 0 116 ?R<R┐- 0 0 117 '?┐аоЄ 0 0 118 "< --"¤н 0 0 119 'л-¤ 0 0 120 ?R§<RўЄ 0 0 121 'Ё┐д?аRЇR<м 0 0 122 ?<R-Є 0 0 123 ?RЄгc ╪ Ў cЄ <мбЄЁc Єа. 0 0 124 '?ў бвRЇR<м 0 0 125 ?- Ї 0 0 126 ?еRвбЄ 0 0 127 'RЇR<?ўR 0 0 128 ? ЄЁв-R? 0 0 129 " <м-??RабЄ 0 0 130 -?<пЎЁ-бЄ 0 0 131 ?RўRЄг§-?жЄ 0 0 132 ?ав?┐ 0 0 Для продолжения нажмите любую клавишу . . . не правильные тут только кодировка не та Добавлено извиняюсь , закоментировал //setlocale(LC_ALL, "RUS"); // рус локаль и все , вывелось по русски |
Сообщ.
#82
,
|
|
|
На данный момент переложил проект на C++CLR WindowsForms, все бы хорошо но опять проблема с кодировкой
switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной textBox2->AppendText(" " + gcnew System::String(p, 0, infCol[j].len) + " "); dR[j] = gcnew System::String(p, 0, infCol[j].len ) ; } break; выводит кракозябы, много уже перерыл , так и не могу найти ответ Прикреплённая картинка
|
Сообщ.
#83
,
|
|
|
Цитата kms @ выводит кракозябы, много уже перерыл , так и не могу найти ответ А в какой кодировке исходно записан текст? Кириллица - она ведь разная бывает. Однобайтовая кодировка (CP-866, KOI8-R, cp1251), многобайтовый юникод (UTF-16, UTF-32), юникод переменной длины (UTF-8)... И это не говоря про всякие префиксы типа BOM, общей длины строки (в стиле Pascal) и т.п. |
Сообщ.
#84
,
|
|
|
Mr.Delphist спасибо что откликнулись , я как раз нашел почти что , но возникла другая заморочка вернее две, ладно по порядку, с кракозяблами частично решилось вот так
textBox2->AppendText(gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n"); но но но почему то вывожу другую таблицу а там опять кракозяблы , сейчас разбираюсь че за прикол , хотя БД одна , Добавлено Mr.Delphist Цитата Mr.Delphist @ А в какой кодировке исходно записан текст? незнаю, а как определить ? |
Сообщ.
#85
,
|
|
|
Цитата Mr.Delphist @ А в какой кодировке исходно записан текст? Кириллица - она ведь разная бывает. Однобайтовая кодировка (CP-866, KOI8-R, cp1251), многобайтовый юникод (UTF-16, UTF-32), юникод переменной длины (UTF-8)... И это не говоря про всякие префиксы типа BOM, общей длины строки (в стиле Pascal) и т.п. Там либо cp-866, либо windows-1251 |
Сообщ.
#86
,
|
|
|
Цитата kms @ незнаю, а как определить ? Можно в Far'е посмотреть. Цитата kms @ Ребята извините перепутал одну букву всего навсего i на j вот исправил CollapsedWrap disabledLine numbers off std::string s(p, Kol[i].len); испрвил на CollapsedWrap disabledLine numbers off std::string s(p, Kol[j].len); Если p это обычная строка с '\0' На конце, то можно проще написать: std::string s = p; |
Сообщ.
#87
,
|
|
|
Цитата KILLER @ Если p это обычная строка с '\0' На конце, то можно проще написать: Нет, там без нуля. |
Сообщ.
#88
,
|
|
|
Цитата Олег М @ Там либо cp-866, либо windows-1251 я не знаю как определить в какой кодировке , в документации к самой СУБД тоже не могу пока найти , существует ли какой нибудь метод чтобы определить в какой кодировке прилетает текст Добавлено Цитата KILLER @ Можно в Far'е посмотреть. щас попробую Добавлено Цитата KILLER @ Если p это обычная строка с '\0' На конце, то можно проще написать: Олег М уже ответил , p - это указатель на буфер в котоорый как раз и прелетают байты которые как раз и надо разобрать где строки где число вообщем в зависимости от параметров столбика как то так |
Сообщ.
#89
,
|
|
|
Цитата kms @ щас попробую Попробуй, открываешь файл и Shift+F8 - там показывает текущую кодировку, плюс список всех поддерживаемых. Добавлено Цитата kms @ Олег М уже ответил , p - это указатель на буфер в котоорый как раз и прелетают байты которые как раз и надо разобрать где строки где число вообщем в зависимости от параметров столбика как то так Да я понял уже. Я просто думал что это обычная строка. |
Сообщ.
#90
,
|
|
|
Тут еще вот выяснелось ,
1.) На большой таблице (93столбика) все съезжает и начинает выводить кракозяблы, а на маленьких таблицах все ок 2.) долго думает |
Сообщ.
#91
,
|
|
|
Цитата kms @ незнаю, а как определить ? Один умный человек предложил кусок кода: Цитата kms @ textBox2->AppendText(gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n"); Циферка 866 как раз намекает, что раз текст показан нормально, значит, исходная кодировка CP-866 (т.е. MS-DOS) Цитата kms @ но но но почему то вывожу другую таблицу а там опять кракозяблы , сейчас разбираюсь че за прикол , хотя БД одна , Кодировка - это не "собственность таблицы", это "собственность строки текста". Теоретически, даже в одной таблице можно хранить кучу кодировок. Типа такого: колонка текста, колонка с номером кодировки этого текста - тогда в каждой строке таблицы может быть своя кодировка. |
Сообщ.
#92
,
|
|
|
Ребята если есть желание попробывать могу тут выложить и СУБД и проект (MSVS2015C++)
|
Сообщ.
#93
,
|
|
|
Цитата kms @ 1.) На большой таблице (93столбика) все съезжает и начинает выводить кракозяблы, а на маленьких таблицах все ок Из за того, что у тебя буфер объявлен char bufOut[1024];, слишком маденький, скорее всего Там надо получать размер буфера и выделять под него память. Где-то я уже это тебе писал, поищи |
Сообщ.
#94
,
|
|
|
Цитата Mr.Delphist @ Кодировка - это не "собственность таблицы", это "собственность строки текста". Теоретически, даже в одной таблице можно хранить кучу кодировок. Типа такого: колонка текста, колонка с номером кодировки этого текста - тогда в каждой строке таблицы может быть своя кодировка. Да я полностью согласен, но но тут другой случай эту Админку к HyTech мы делаем как бы с ноля и в наличии есть dll и h вот начальный код т.е. конект к серверу , Получить информацию об соединении, выполнить SQL-запрос и получить ответ распарсить его это уже есть только вот с оговоркой большие таблицы начинает поля сьезжать вот большую часть кода отрихтовал Олег_М Добавлено Цитата Олег М @ Из за того, что у тебя буфер объявлен char bufOut[1024];, слишком маденький, скорее всего Там надо получать размер буфера и выделять под него память. Где-то я уже это тебе писал, поищи да точно , точно точно , как всегда прав Добавлено char bufOut[1024 * pCol]; // Адрес буфера для присылаемых записей. ругается выражение должно иметь константное значение |
Сообщ.
#95
,
|
|
|
Цитата kms @ ругается выражение должно иметь константное значение Надо через new выделять. И уж точно не 1024 * pCol. Там была функция получения размера записи, смотри внимательнее |
Сообщ.
#96
,
|
|
|
Сообщ.
#97
,
|
|
|
Вообщем , сделал так
...... . . int x = 4 * 1024; char *bufOut = new char[x]; for (long i = 0; i < pStr; i++)//идем по строкам { DataRow ^dR = dT->NewRow();// Добавляем новую строку в виртуальную таблицу hcSqlReadResults(pOper, i, bufOut , x , &cntOut);// Чтение результатов . . ..... почему именно x = 4 * 1024; не знаю , перебирал и Размер читаемой записи в байтах pRecSize и Размер считанной информации в байтах cntOp и всякие другие варианты а вот "количество байтов данных , помещённых в буфер пользователя cntOut " из функции hcSqlReadResults(pOper, i, bufOut , x , &cntOut);// Чтение результатов как вставить опять же в эту функцию не знаю , че два раза ее вызывать что ли |
Сообщ.
#98
,
|
|
|
Цитата kms @ почему именно x = 4 * 1024; не знаю , перебирал и Размер читаемой записи в байтах pRecSize и Размер считанной информации в байтах cntOp и всякие другие варианты А в доке не оно разве написано? http://hytechdb.ru/index.php?s=docs&ru=V25...OpenResults.htm Цитата unsigned * pRecSize Адрес слова, в которое запишется размер читаемой записи в байтах. Если размер записи не нужен, то можно задать . Вот этот параметр - не размер буфера, который нужно передать в hcSqlReadResults ? Добавлено Цитата kms @ а вот "количество байтов данных , помещённых в буфер пользователя cntOut " из функции hcSqlReadResults(pOper, i, bufOut , x , &cntOut);// Чтение результатов как вставить опять же в эту функцию не знаю , че два раза ее вызывать что ли Это скорее всего - сколько оно реально прочитало. Т.е. как я понимаю, сначало нужно вызвать hcSqlOpenResults, она как раз в pRecSize запишет размер буфера, необходимого для функции hcSqlReadResults, ты делаешь буфер размером с pRecSize, который вернула функция hcSqlOpenResults. И передаешь этот буфер в hcSqlReadResults, а уже hcSqlReadResults в последний параметр запишет: Цитата unsigned *cnt) /* Сколько прочитали */ Потому как "сколько предполагается прочитать" может отличаться от "сколько реально прочитали". Добавлено Я думаю надо было так делать: unsigned x = -1; hcSqlOpenResults(pOper, &x) char *bufOut = new char[x]; /**/ for (long i = 0; i < pStr; i++)//идем по строкам { DataRow ^dR = dT->NewRow();// Добавляем новую строку в виртуальную таблицу /*В cntOut - запишется сколько реально байтов данных функция поместила в буфер*/ hcSqlReadResults(pOper, i, bufOut , x , &cntOut);// Чтение результатов Добавлено Причем у тебя ведь так и было написано раньше. |
Сообщ.
#99
,
|
|
|
Цитата KILLER @ Вот этот параметр - не размер буфера, который нужно передать в hcSqlReadResults ? совершенно верно , я эти доки уже 3года читаю , Вы правельно все говорите но почему то не получается вот код, для удобства я все пишу в одной процедуре на кнопку (еще раз повторю проект MSVS2015C++CLRWinForms) Скрытый текст private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { hcERR err; // Код ошибки hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcHSTMT pOper; // Адрес памяти, куда будет записан идентификатор оператора. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации int pCol = 0; // количество колонок hcRECNO pStr = 0; // количество строк unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . unsigned cntOut = 0; // для ф-ции "Чтение результатов" Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. char *strConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text);// Сервер char *strLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox4->Text);// Логин char *strPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox5->Text);// Пароль char *strSql = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox6->Text);// поле SQL-запроса if (err = hcSqlInit(&Init) != 0) textBox2->AppendText("Ошибка с параметрами инициализации \n"); // Инициализация клиентской части if (hcSqlCheckInit() < 0) textBox2->AppendText("Ошибка завершения инициализации \n"); // Проверка завершения инициализации err = hcSqlAllocConnect(&pdb); // Создать соединение err = hcSqlConnect(pdb, strConnect, strLogin, strPassword); //Установить связь с СУБД // "tcpip:/localhost:13000" err = hcSqlAllocStmt(pdb, &pOper); // Создать оператор err = hcSqlExecDirect(pOper, strSql ); // Выполняем SQLзапрос err = hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата err = hcSqlRowCount(pOper, &pStr); // Получить количество строк результата hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" err = hcSqlOpenResults(pOper, &pRecSize); // Открытие результатов для чтения DataTable ^dT = gcnew DataTable() ; for (int k = 0; k < pCol;k++) dT->Columns->Add("ст" + k ); for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, infCol, pCol * 4 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе textBox2->AppendText("Размер читаемой зап. в байтах (из ф-ции hcSqlOpenResults) pRecSize = " + pRecSize + "\r\n"); textBox2->AppendText("Размер считанной инф-ции в байтах (из ф-ции hcSqlGetStmtAttr) cntOp = " + cntOp + "\r\n"); int x = 4 * 1024; // размер этого буфера char *bufOut = new char[x]; // Адрес буфера для присылаемых записей. for (long i = 0; i < pStr; i++)//идем по строкам { DataRow ^dR = dT->NewRow();// Добавляем новую строку в виртуальную таблицу hcSqlReadResults(pOper, i, bufOut , x , &cntOut);// Чтение результатов textBox2->AppendText("Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = " + cntOut + "\r\n"); char *p = bufOut; // делаем указатель на буфер for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной // textBox2->AppendText(gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n"); dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)); } break; case HSCLI_ET_ARRA: { // 1 Массив байтов заданной длины // textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p) ; } break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p) ; } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p) ; } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p) ; } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p) ; } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len; } dT->Rows->Add(dR); } dataGridView2->DataSource = dT; hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы //------------------------------------------------------------------------------------ }//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\\ |
Сообщ.
#100
,
|
|
|
результат
Прикреплённая картинка
Добавлено но вот момент если посмотреть весь вывод отладочной инф. Скрытый текст Размер читаемой зап. в байтах (из ф-ции hcSqlOpenResults) pRecSize = 54 Размер считанной инф-ции в байтах (из ф-ции hcSqlGetStmtAttr) cntOp = 640 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 4050 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3996 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3942 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3888 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3834 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3780 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3726 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3672 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3618 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3564 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3510 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3456 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3402 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3348 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3294 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3240 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3186 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3132 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3078 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 3024 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2970 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2916 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2862 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2808 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2754 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2700 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2646 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2592 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2538 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2484 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2430 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2376 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2322 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2268 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2214 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2160 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2106 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 2052 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1998 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1944 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1890 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1836 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1782 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1728 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1674 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1620 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1566 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1512 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1458 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1404 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1350 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1296 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1242 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1188 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1134 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1080 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 1026 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 972 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 918 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 864 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 810 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 756 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 702 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 648 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 594 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 540 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 486 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 432 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 378 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 324 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 270 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 216 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 162 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 108 Кол-во байтов, помещённых в буфер пользователя (из ф-ции hcSqlReadResults) = 54 Добавлено после вывода 56 строки размер буфера начинает падать, до размеров Размер читаемой зап. в байтах (из ф-ции hcSqlOpenResults) pRecSize = 54 Добавлено KILLER прошу прощения , 10 раз пробывал были кракозяблы щас с утра решил сотый раз перепроверить чтобы вам выложить скрины что мол не получается pRecSize передать в ф-цию, и тут бах все пошло , вообщем сделал . . . char *bufOut = new char[pRecSize]; // Адрес буфера для присылаемых записей. for (long i = 0; i < pStr; i++)//идем по строкам { DataRow ^dR = dT->NewRow();// Добавляем новую строку в виртуальную таблицу hcSqlReadResults(pOper, i, bufOut , pRecSize, &cntOut);// Чтение результатов char *p = bufOut; // делаем указатель на буфер . . . Добавлено теперь осталось последнее , самое главное : 1) название столбцов 2) скорость |
Сообщ.
#101
,
|
|
|
в структуре о столбиках есть пунктик имя поля
hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, infCol, pCol * 4 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе dataGridView1->Rows->Add("nn", "С Т О Л Б И К № ", i + 1); dataGridView1->Rows->Add("nn", "Порядковый номер алиаса aliasno", infCol[i].aliasno); dataGridView1->Rows->Add("nn", "Номер поля в таблице fieldno", infCol[i].fieldno); dataGridView1->Rows->Add("nn", "Тип type", infCol[i].type); dataGridView1->Rows->Add("nn", "Длина поля в байтах len", infCol[i].len); dataGridView1->Rows->Add("nn", "Смещение поля от начала лог.зап. off", infCol[i].off); // dataGridView1->Rows->Add("nn", "Имя кодификатора.только для coder(MYCODER, code). coder", infCol[i].coder); dataGridView1->Rows->Add("nn", "Имя поля в таблице fname", infCol[i].fname ); dataGridView1->Rows->Add("nn", "Формат выражения CURS_OUTEXPR func", infCol[i].func); // dataGridView1->Rows->Add("nn", "Переименование поля, asname", infCol[i].asname ); dataGridView1->Rows->Add("nn", "Ключевитость поля, key", infCol[i].key); dataGridView1->Rows->Add("nn", "Сквозной номер поля в результате resno", infCol[i].resno); } но там почему то пусто , и на выводе , и в дебагере смотрю Добавлено вот Информация о колонке результата и вот еще косяк ... for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, infCol, pCol * 4 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе .... тут я тоже от балды умножаю на 4 , потому что тоже перепробывал кучу варинтов ни че не выводится , ставлю 4 , и все идет вот сейчас infCol[i].fname забит нулями |
Сообщ.
#102
,
|
|
|
насколько я понял надо еще вызвать функцию
hcERR hcSqlSetConnectAttr( hcHDB h, /* Идентификатор соединения */ unsigned option, /* Режим */ const void *pValue, /* Значение или буфер значения */ unsigned size); /* Размер буфера */ (параметр соединения HSCLI_ATTR_FLD_VERBOSE функции hcSqlSetConnectAttr или hcSqlSetStmtAttr). |
Сообщ.
#103
,
|
|
|
делаю так
err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, pl, 0 ); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях но что то пока все равно нули |
Сообщ.
#104
,
|
|
|
Цитата kms @ в структуре о столбиках есть пунктик имя поля Ну во первых, цикл у тебя идет до pCol, а он чему равен? Во вторых - hcSqlGetStmtAttr что возвращает? Ошибку не возвращает? Цитата kms @ насколько я понял надо еще вызвать функцию hcERR hcSqlSetConnectAttr( Да, причем там написано что: Цитата Данное поле заполняется, если разрешено запрашивать с сервера расширенную информацию о полях (параметр соединения HSCLI_ATTR_FLD_VERBOSE функции hcSqlSetConnectAttr или hcSqlSetStmtAttr). Т.е. это нужно сделать и посмотреть на результат. |
Сообщ.
#105
,
|
|
|
Цитата KILLER @ Ну во первых, цикл у тебя идет до pCol, а он чему равен? количеству столбиков |
Сообщ.
#106
,
|
|
|
Цитата kms @ но что то пока все равно нули Покажи весь код |
Сообщ.
#107
,
|
|
|
Сообщ.
#108
,
|
|
|
У тебя hcSqlSetStmtAttr ошибку возвращает. Что она значит?
|
Сообщ.
#109
,
|
|
|
Цитата Олег М @ Покажи весь код вот private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { hcERR err; // Код ошибки hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcHSTMT pOper; // Адрес памяти, куда будет записан идентификатор оператора. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации int pCol = 0; // количество колонок hcRECNO pStr = 0; // количество строк unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . unsigned cntOut = 0; // для ф-ции "Чтение результатов" Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. char *strConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text);// Сервер char *strLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox4->Text);// Логин char *strPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox5->Text);// Пароль char *strSql = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox6->Text);// поле SQL int ph = 1; // для ф-ции hcSqlSetConnectAttr и hcSqlSetStmtAttr int *pl = &ph; // if (err = hcSqlInit(&Init) != 0) textBox2->AppendText("Ошибка с параметрами инициализации \n"); // Инициализация клиентской части if (hcSqlCheckInit() < 0) textBox2->AppendText("Ошибка завершения инициализации \n"); // Проверка завершения инициализации err = hcSqlAllocConnect(&pdb); // Создать соединение textBox2->AppendText("Создать соединение err = " + err + "\r\n"); // отладка err = hcSqlSetConnectAttr(pdb, HSCLI_ATTR_FLD_VERBOSE, &pl, 0); // ф-ция "Изменение параметров соединения" textBox2->AppendText("hcSqlSetConnectAttr c параметром HSCLI_ATTR_FLD_VERBOSE err= " + err + "\r\n"); // отладка err = hcSqlConnect(pdb, strConnect, strLogin, strPassword); //Установить связь с СУБД // "tcpip:/localhost:13000" err = hcSqlAllocStmt(pdb, &pOper); // Создать оператор err = hcSqlExecDirect(pOper, strSql); // Выполняем SQLзапрос GROUP TAB TABLES USERSPEC UGROUPS "fix all; select * from CITY;" err = hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата err = hcSqlRowCount(pOper, &pStr); // Получить количество строк результата err = hcSqlOpenResults(pOper, &pRecSize); // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу for (int k = 0; k < pCol; k++) // создаем в ней столько колонок сколько в полученном результате dT->Columns->Add("ст" + k); textBox2->AppendText("pl = " + *pl + "\r\n"); // отладка textBox2->AppendText("Кол-во столбиков pCol = " + pCol + "\r\n"); // отладка for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, infCol, pCol * 4 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе textBox2->AppendText("очередной проход hcSqlGetStmtAttr err = " + err + "\r\n"); err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, &pl, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях textBox2->AppendText("hcSqlSetStmtAttr c параметром HSCLI_ATTR_FLD_VERBOSE = " + err + "\r\n"); dataGridView1->Rows->Add("nn", "С Т О Л Б И К № ", i + 1); dataGridView1->Rows->Add("nn", "Порядковый номер алиаса aliasno", infCol[i].aliasno); dataGridView1->Rows->Add("nn", "Номер поля в таблице fieldno", infCol[i].fieldno); dataGridView1->Rows->Add("nn", "Тип type", infCol[i].type); dataGridView1->Rows->Add("nn", "Длина поля в байтах len", infCol[i].len); dataGridView1->Rows->Add("nn", "Смещение поля от начала лог.зап. off", infCol[i].off); // dataGridView1->Rows->Add("nn", "Имя кодификатора.только для coder(MYCODER, code). coder", infCol[i].coder); for (int x = 0; x < 32; x++) textBox2->AppendText(infCol[i].fname[x] + " " ); textBox2->AppendText( "\r\n"); //dataGridView1->Rows->Add("nn", "Имя поля в таблице fname", infCol[i].fname ); dataGridView1->Rows->Add("nn", "Формат выражения CURS_OUTEXPR func", infCol[i].func); // dataGridView1->Rows->Add("nn", "Переименование поля, asname", infCol[i].asname ); dataGridView1->Rows->Add("nn", "Ключевитость поля, key", infCol[i].key); dataGridView1->Rows->Add("nn", "Сквозной номер поля в результате resno", infCol[i].resno); } char *bufOut = new char[pRecSize]; // Адрес буфера для присылаемых записей. for (long i = 0; i < pStr; i++)//идем по строкам { DataRow ^dR = dT->NewRow();// Добавляем новую строку в виртуальную таблицу const auto err = hcSqlReadResults(pOper, i, bufOut, pRecSize, &cntOut);// Чтение результатов char *p = bufOut; // делаем указатель на буфер for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной //textBox2->AppendText(gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n"); dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)); } break; case HSCLI_ET_ARRA: { // 1 Массив байтов заданной длины // textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p); } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p); } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len; } //textBox1->AppendText("\r\n "); dT->Rows->Add(dR); } dataGridView2->DataSource = dT; hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы }//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\\ Добавлено Цитата Олег М @ У тебя hcSqlSetStmtAttr ошибку возвращает. Что она значит? -20009 — Неправильная версия сервера Данная клиентская библиотека не может работать с сервером этой версии. Необходимо обновить сервер. |
Сообщ.
#110
,
Сообщение отклонено: JoeUser -
|
Сообщ.
#111
,
Сообщение отклонено: JoeUser -
|
Сообщ.
#112
,
|
|
|
Цитата Олег М @ Что она значит? Похоже вот это http://hytechdb.ru/index.php?s=docs&ru=V25...i/ers20000.htm: Цитата -20009 — Неправильная версия сервера Данная клиентская библиотека не может работать с сервером этой версии. Необходимо обновить сервер. |
Сообщ.
#113
,
|
|
|
Скорее всего, hcSqlSetStmtAttr надо вызывать непосредственно после или перед hcSqlConnect, для pdb - hcSqlSetStmtAttr(pdb, .........
|
Сообщ.
#114
,
Сообщение отклонено: JoeUser -
|
Сообщ.
#115
,
Сообщение отклонено: JoeUser -
|
Сообщ.
#116
,
|
|
|
Цитата Олег М @ Скорее всего, hcSqlSetStmtAttr надо вызывать непосредственно после или перед hcSqlConnect, для pdb - hcSqlSetStmtAttr(pdb да да я это уже перепробывал и в той и в той вариации , помоему я опять не кашерно загоняю единичку в hcSqlSetConnectAttr вот что сказано в описании Параметр оператора HSCLI_ATTR_FLD_VERBOSE Параметр оператора HSCLI_ATTR_FLD_VERBOSE определяет, разрешено ли клиентской части запрашивать с сервера расширенную информацию о полях при выполнении SQL-запросов. Не все версии сервера БД могут присылать расширенную информацию. Параметр оператора HSCLI_ATTR_FLD_VERBOSE может принимать значение 0 («Запрещено») или 1 («Разрешено»). При создании оператора параметр HSCLI_ATTR_FLD_VERBOSE получает значение, которое имеет параметр соединения HSCLI_ATTR_FLD_VERBOSE. При вызове функции hcSqlSetStmtAttr параметр функции pValue принимает устанавливаемое значение параметра оператора HSCLI_ATTR_FLD_VERBOSE, а параметр функции size должен быть равен 0. |
Сообщ.
#117
,
|
|
|
Цитата kms @ err = hcSqlSetConnectAttr(pdb, HSCLI_ATTR_FLD_VERBOSE, &pl, 0); // ф-ция "Изменение параметров соединения" А если изменить вызов этой функции, на такую: hcSqlSetStmtAttr ? |
Сообщ.
#118
,
|
|
|
Цитата kms @ да да я это уже перепробывал и в той и в той вариации , помоему я опять не кашерно загоняю единичку в hcSqlSetConnectAttr вот что сказано в описании Здесь надо не &p1, а &ph, либо просто p1 err = hcSqlSetConnectAttr(pdb, HSCLI_ATTR_FLD_VERBOSE, pl, 0); // ф-ция "Изменение параметров соединения" Добавлено А это вообще убери err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, &pl, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях |
Сообщ.
#119
,
|
|
|
если вызываю hcSqlSetConnectAttr c параметром HSCLI_ATTR_FLD_VERBOSE до Создать соединение err = -97 Неправильный идентификатор оператора (номер курсора)
Передан неправильный идентификатор оператора (курсора), или идентификатор оператора, который уже удален. потом Создать соединение err = 0 а потом hcSqlSetConnectAttr c параметром HSCLI_ATTR_FLD_VERBOSE err= -20009 pl = 1 Кол-во столбиков pCol = 5 насчет -20009 — Неправильная версия сервера , на самом деле может быть только наоборот , библиотека старей сервера , Добавлено Цитата KILLER @ А если изменить вызов этой функции, на такую: hcSqlSetStmtAttr ? да я вот щас пробую Добавлено Цитата Олег М @ Здесь надо не &p1, а &ph, либо просто p1 err = hcSqlSetConnectAttr(pdb, HSCLI_ATTR_FLD_VERBOSE, pl, 0); // ф-ция "Изменение параметров соединения" ок щас перебираю эти варианты Добавлено Цитата Олег М @ А это вообще убери err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, &pl, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях убрал Добавлено из дебагера pl - 0x003AECC4 Добавлено из дебага &ph - 1 Добавлено делаю int ph = 1; // для ф-ции hcSqlSetConnectAttr int *pl = &ph; // и hcSqlSetStmtAttr textBox2->AppendText("ph = " + ph + "\r\n"); // отладка textBox2->AppendText("Кол-во столбиков pCol = " + pCol + "\r\n"); // отладка err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, &ph, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях textBox2->AppendText("hcSqlSetStmtAttr c параметром HSCLI_ATTR_FLD_VERBOSE = " + err + "\r\n"); for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, infCol, pCol * 4 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе dataGridView1->Rows->Add("nn", "С Т О Л Б И К № ", i + 1); dataGridView1->Rows->Add("nn", "Порядковый номер алиаса aliasno", infCol[i].aliasno); dataGridView1->Rows->Add("nn", "Номер поля в таблице fieldno", infCol[i].fieldno); dataGridView1->Rows->Add("nn", "Тип type", infCol[i].type); dataGridView1->Rows->Add("nn", "Длина поля в байтах len", infCol[i].len); dataGridView1->Rows->Add("nn", "Смещение поля от начала лог.зап. off", infCol[i].off); // dataGridView1->Rows->Add("nn", "Имя кодификатора.только для coder(MYCODER, code). coder", infCol[i].coder); for (int x = 0; x < 32; x++) textBox2->AppendText(infCol[i].fname[x] ); char *pNP = infCol[i].fname; textBox2->AppendText(gcnew String(pNP, 0, 10, System::Text::Encoding::GetEncoding(866))); // отладка //dataGridView1->Rows->Add("nn", "Имя поля в таблице fname", infCol[i].fname ); dataGridView1->Rows->Add("nn", "Формат выражения CURS_OUTEXPR func", infCol[i].func); // dataGridView1->Rows->Add("nn", "Переименование поля, asname", infCol[i].asname ); dataGridView1->Rows->Add("nn", "Ключевитость поля, key", infCol[i].key); dataGridView1->Rows->Add("nn", "Сквозной номер поля в результате resno", infCol[i].resno); } результат Создать соединение err = 0 ph = 1 Кол-во столбиков pCol = 5 hcSqlSetStmtAttr c параметром HSCLI_ATTR_FLD_VERBOSE = 0 |
Сообщ.
#120
,
|
|
|
Ну а дальше? Выводит?
Добавлено Цитата kms @ err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, &ph, 0); Если не выводит, попробуй еще вот так переделать: err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, ph, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях |
Сообщ.
#121
,
|
|
|
Ребята , вдруг всетаки решитесь глянуть хоть одним глазком на HyTech https://yadi.sk/d/Aw5CyDg33FrdpD весит 3М , ложится просто на С:\ и все запускаете и оно работает
Добавлено Цитата KILLER @ Ну а дальше? Выводит? Добавлено 9 минут назад Цитата kms @ 56 минут назад err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, &ph, 0); да да , в смысле про нолики , дело в том что не пойму нолики не выводятся если делаю вывод вот так for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, infCol, pCol * 4 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе dataGridView1->Rows->Add("nn", "С Т О Л Б И К № ", i + 1); dataGridView1->Rows->Add("nn", "Порядковый номер алиаса aliasno", infCol[i].aliasno); dataGridView1->Rows->Add("nn", "Номер поля в таблице fieldno", infCol[i].fieldno); dataGridView1->Rows->Add("nn", "Тип type", infCol[i].type); dataGridView1->Rows->Add("nn", "Длина поля в байтах len", infCol[i].len); dataGridView1->Rows->Add("nn", "Смещение поля от начала лог.зап. off", infCol[i].off); // dataGridView1->Rows->Add("nn", "Имя кодификатора.только для coder(MYCODER, code). coder", infCol[i].coder); for (int x = 0; x < 32; x++) textBox2->AppendText(gcnew String(infCol[i].fname, 0, 10, System::Text::Encoding::GetEncoding(866))); char *pNP = infCol[i].fname; textBox2->AppendText(gcnew String(pNP, 0, 10, System::Text::Encoding::GetEncoding(866))); // отладка //dataGridView1->Rows->Add("nn", "Имя поля в таблице fname", infCol[i].fname ); dataGridView1->Rows->Add("nn", "Формат выражения CURS_OUTEXPR func", infCol[i].func); // dataGridView1->Rows->Add("nn", "Переименование поля, asname", infCol[i].asname ); dataGridView1->Rows->Add("nn", "Ключевитость поля, key", infCol[i].key); dataGridView1->Rows->Add("nn", "Сквозной номер поля в результате resno", infCol[i].resno); } Добавлено Цитата KILLER @ Если не выводит, попробуй еще вот так переделать: err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, ph, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях если так делаю то ошибка ОшибкаC2664"hcERR hcSqlSetStmtAttr(hcHSTMT,unsigned int,void *,unsigned int)": невозможно преобразовать аргумент 3 из "int" в "void *"RudderHyTechc:\users\admin\desktop\rudderhytech\rudderhytech\MyForm.h781 |
Сообщ.
#122
,
|
|
|
Цитата kms @ err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, infCol, pCol * 4 * sizeof(hcSqlAliasInfoT), &cntOp);// Получить информацию об операторе А почему у тебя здесь стоит sizeof(hcSqlAliasInfoT), когда должен быть sizeof(hcSqlDstInfoT)? |
Сообщ.
#123
,
|
|
|
Цитата kms @ Ребята , вдруг всетаки решитесь глянуть хоть одним глазком на HyTech https://yadi.sk/d/Aw5CyDg33FrdpD весит 3М , ложится просто на С:\ и все запускаете и оно работает И что там смотреть? Там одни бинарники. Добавлено Цитата kms @ ОшибкаC2664"hcERR hcSqlSetStmtAttr(hcHSTMT,unsigned int,void *,unsigned int)": невозможно преобразовать аргумент 3 из "int" в "void *"RudderHyTechc:\users\admin\desktop\rudderhytech\rudderhytech\MyForm.h781 Попробуй преобразование типов сделать: err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)ph, 0); |
Сообщ.
#124
,
|
|
|
Цитата KILLER @ Попробуй преобразование типов сделать: err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)ph, 0); Думаю, то же самое скажет |
Сообщ.
#125
,
|
|
|
Цитата Олег М @ Думаю, то же самое скажет Почему? По идее int в void* должно норм преобразовать, по крайней мере ошибки компиляции не должно быть. Другое дело ошибка исполнения, но тогда не совсем понятно что они там в доке имели ввиду под: Цитата Адрес значения параметра или само значение параметра, если оно имеет тип целого числа (int/long) |
Сообщ.
#126
,
|
|
|
Цитата KILLER @ Почему? По идее int в void* должно норм преобразовать, по крайней мере ошибки компиляции не должно быть. Другое дело ошибка исполнения, но тогда не совсем понятно что они там в доке имели ввиду под: Цитата Адрес значения параметра или само значение параметра, если оно имеет тип целого числа (int/long) Кстати, да. |
Сообщ.
#127
,
|
|
|
Цитата Олег М @ А почему у тебя здесь стоит sizeof(hcSqlAliasInfoT), когда должен быть sizeof(hcSqlDstInfoT)? щас смотрю Добавлено Цитата Олег М @ А почему у тебя здесь стоит sizeof(hcSqlAliasInfoT), когда должен быть sizeof(hcSqlDstInfoT)? оппа па па чето поперло поставил выхлоп Создать соединение err = 0 Создать оператор 1раз = 0 hcSqlSetStmtAttr c параметром HSCLI_ATTR_FLD_VERBOSE = 0 Создать оператор 2раз = 0 ph = 1 Кол-во столбиков pCol = 5 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════-51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════-51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════-51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════-51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 -51 ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ Добавлено сделал так hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, infCol, sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе Добавлено Цитата KILLER @ И что там смотреть? Там одни бинарники. саму папку HyTech из архива ложишь на диск С:\ и запускаешь файл sql64.exe (exe-шник там один) и все сервер СУБД HyTech работает, а уже к нему подключаешься из проекта Добавлено Цитата KILLER @ Попробуй преобразование типов сделать: err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)ph, 0); да так попробывал тоже не чего нули |
Сообщ.
#128
,
|
|
|
Цитата kms @ и все сервер СУБД HyTech работает, а уже к нему подключаешься из проекта Из какого проекта? |
Сообщ.
#129
,
|
|
|
Цитата KILLER @ Почему? По идее int в void* должно норм преобразовать, по крайней мере ошибки компиляции не должно быть. Другое дело ошибка исполнения, но тогда не совсем понятно что они там в доке имели ввиду под: Цитата Адрес значения параметра или само значение параметра, если оно имеет тип целого числа (int/long) вот до сих пор расшифровываю , в дебаге смотрю туда единичка точно залетает но переключатся чето не хочет Добавлено Цитата KILLER @ Из какого проекта? ну это если вдруг возникнет желание потестить то что щас делаем |
Сообщ.
#130
,
|
|
|
Ты напиши простейший проект, выложи его сюда вместе с хидерами от хайтек и либой.
|
Сообщ.
#131
,
|
|
|
Цитата KILLER @ Ты напиши простейший проект, выложи его сюда вместе с хидерами от хайтек и либой. https://yadi.sk/d/7MDSxPOy3Fs8Y9 Под MSVS2015C++ |
Сообщ.
#132
,
|
|
|
У меня вот эта строка возвращает ошибку:
err = hcSqlConnect(pdb, strConnect, strLogin, strPassword); //Установить связь с СУБД -6034 Не могу ее найти в кодах ошибки, может там еще что то поднять нужно? Добавлено К слову сервер я поставил, но не могу найти куда он установился и в пакете инсталяционном никаких путей нет. Может сервер надо запустить? |
Сообщ.
#133
,
|
|
|
В общем мне кажеться скопировать и запустить мало. Надо еще что то настраивать, пока летит на коннекте с ошибкой.
|
Сообщ.
#134
,
|
|
|
Цитата kms @ сделал так hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, infCol, sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе Это тебе должно вернуть, что буфер слишком маленький. Надо hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе Добавлено И всегда проверяй, что тебе возвращает функция |
Сообщ.
#135
,
|
|
|
Сообщ.
#136
,
|
|
|
Сообщ.
#137
,
|
|
|
после этого запускаем проект , и даже если что то идет с ошибкой то монитор сервера все равно покажет сообщение,
тоесть после каждого соединения экран будет таким Прикреплённая картинка
Добавлено долго думал над этим Цитата KILLER @ Почему? По идее int в void* должно норм преобразовать, по крайней мере ошибки компиляции не должно быть. Другое дело ошибка исполнения, но тогда не совсем понятно что они там в доке имели ввиду под: и вот этим Цитата Олег М @ Кстати, да. и взял брякнул вот так err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (int*)1, 0); вы может не поверите оно работает Добавлено Цитата Олег М @ Это тебе должно вернуть, что буфер слишком маленький. Надо hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе ОК сделал Добавлено Цитата Олег М @ И всегда проверяй, что тебе возвращает функция ОК понял |
Сообщ.
#138
,
|
|
|
Ребята ну вот выхлоп
Прикреплённая картинка
Добавлено И осталось совсем мелочовка, ребят помогите самое главное , алгоритм , сейчас этот алгоритм работает 30сек на 200000 строк 93столбика прямая выборка таблицы, а на родной консоле выберается и выводится на экран за 1сек, даже наверное меньше, вот Помогите пожалуста оптимизировать код до приемлимых скоростей |
Сообщ.
#139
,
|
|
|
Сейчас код все в одной кнопке (для удобства отладки, и демонстрации другим , чтобы небыло переходов и лишних объяснений )
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { hcERR err; // Код ошибки hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcHSTMT pOper; // Адрес памяти, куда будет записан идентификатор оператора. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации int pCol = 0; // количество колонок hcRECNO pStr = 0; // количество строк unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . unsigned cntOut = 0; // для ф-ции "Чтение результатов" Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. char *strConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text);// Сервер char *strLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox4->Text);// Логин char *strPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox5->Text);// Пароль char *strSql = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox6->Text);// поле SQL if (err = hcSqlInit(&Init) != 0) textBox2->AppendText("Ошибка с параметрами инициализации \n"); // Инициализация клиентской части if (hcSqlCheckInit() < 0) textBox2->AppendText("Ошибка завершения инициализации \n"); // Проверка завершения инициализации err = hcSqlAllocConnect (&pdb); //----------------------------- Создать соединение err = hcSqlConnect (pdb, strConnect, strLogin, strPassword); //Установить связь с СУБД err = hcSqlAllocStmt (pdb, &pOper); // Создать оператор err = hcSqlSetStmtAttr (pOper, HSCLI_ATTR_FLD_VERBOSE, (int*)1, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях err = hcSqlExecDirect (pOper, strSql); // Выполняем SQLзапрос err = hcSqlNumResultCols (pOper, &pCol); // Получить количество колонок результата err = hcSqlRowCount (pOper, &pStr); // Получить количество строк результата err = hcSqlOpenResults (pOper, &pRecSize); // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, infCol , pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе char *pNP = infCol[i].fname; dT->Columns->Add(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866))); textBox2->AppendText(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866)) + "\r\n"); // отладка } char *bufOut = new char[pRecSize]; // Адрес буфера для присылаемых записей. for (long i = 0; i < pStr; i++) //идем по строкам { DataRow ^dR = dT->NewRow(); // Добавляем новую строку в виртуальную таблицу err = hcSqlReadResults(pOper, i, bufOut, pRecSize, &cntOut);// Чтение результатов char *p = bufOut; // делаем указатель на буфер for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной //textBox2->AppendText(gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n"); dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)); } break; case HSCLI_ET_ARRA: { // 1 Массив байтов заданной длины // textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p); } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p); } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len; } //textBox1->AppendText("\r\n "); dT->Rows->Add(dR); } dataGridView2->DataSource = dT; hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы }//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\\ если вставить с MSVS2008C++ по MSVS2015C++ будет работать, а вот это надо добавить к проекту Прикреплённый файлDLL_H_LIB__HyTech.rar (190,42 Кбайт, скачиваний: 86) Добавлено вот весь проект уже со всеми либамиHyTech открыли, запустили, работает. под MSVS2015C++ https://yadi.sk/d/Qwwzs8Yv3Furp4 |
Сообщ.
#140
,
|
|
|
Цитата kms @ for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, i, infCol , pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе char *pNP = infCol[i].fname; dT->Columns->Add(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866))); textBox2->AppendText(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866)) + "\r\n"); // отладка } По-моему, этот цикл можно сделать так err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol , pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { char *pNP = infCol[i].fname; dT->Columns->Add(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866))); textBox2->AppendText(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866)) + "\r\n"); // отладка } Добавлено Цитата kms @ Помогите пожалуста оптимизировать код до приемлимых скоростей Сначала надо выяснить, что именно тормозит. Подозреваю, что это не база, а добавление в список Цитата kms @ DataRow ^dR = dT->NewRow(); // Добавляем новую строку в виртуальную таблицу Попробуй убрать его и посмотреть сколько будет отрабатывать for (long i = 0; i < pStr; i++) //идем по строкам { ///////// DataRow ^dR = dT->NewRow(); // Добавляем новую строку в виртуальную таблицу err = hcSqlReadResults(pOper, i, bufOut, pRecSize, &cntOut);// Чтение результатов /******************** char *p = bufOut; // делаем указатель на буфер for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { ................................... } p += infCol[j].len; } //textBox1->AppendText("\r\n "); dT->Rows->Add(dR); *******/ } |
Сообщ.
#141
,
|
|
|
Цитата Олег М @ По-моему, этот цикл можно сделать так ОК пробую, да за разом как раз ты зашел , хотел спросить давай может еще тут выложим это хозяйство на ветку Проекты Добавлено ты как не против , может кому интересно станет может кому понадобится та и вообще может кто еще присоединится, я там уже сделал окошко Опрограмме буду туда всех вписывать кот принимает участие ты не против Добавлено Цитата Олег М @ По-моему, этот цикл можно сделать так err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol , pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { char *pNP = infCol[i].fname; dT->Columns->Add(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866))); textBox2->AppendText(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866)) + "\r\n"); // отладка } точно работает а я до последнего сомневался насчет заполнения структуры параметров я думал только в цикле надо, но время выполнения пока почти 1мин (в смысле таблицы на 200 000 строк 93столбца) |
Сообщ.
#142
,
|
|
|
Цитата kms @ но время выполнения пока почти 1мин (в смысле таблицы на 200 000 строк 93столбца) А ты сделал, то что я написал, чтоб проверить, где тормоза? |
Сообщ.
#143
,
|
|
|
Цитата Олег М @ Попробуй убрать его и посмотреть сколько будет отрабатывать for (long i = 0; i < pStr; i++) //идем по строкам { ///////// DataRow ^dR = dT->NewRow(); // Добавляем новую строку в виртуальную таблицу Уже пробывал , с самого начала вывод пускал сразу в dataGridView2 , вот и оно колбасило больше часа (в смысле таб200000стр93ст) , потом подумал про массив но нельзя так как массив должен быть однородным, вот пока остановился на DataTable Добавлено а в смсле просто закаментировать , все понял , тоесть вывод не куда не пускать просто чисто получение запроса ОК Добавлено ну вот сделал проверил , также 1мин |
Сообщ.
#144
,
|
|
|
Цитата kms @ ну вот сделал проверил , также 1мин Покажи код |
Сообщ.
#145
,
|
|
|
сейччас
Добавлено private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e){ hcERR err; // Код ошибки hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcHSTMT pOper; // Адрес памяти, куда будет записан идентификатор оператора. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации int pCol = 0; // количество колонок hcRECNO pStr = 0; // количество строк unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . unsigned cntOut = 0; // для ф-ции "Чтение результатов" Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. char *strConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text);// Сервер char *strLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox4->Text);// Логин char *strPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox5->Text);// Пароль char *strSql = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox6->Text);// поле SQL if (err = hcSqlInit(&Init) != 0) textBox2->AppendText("Ошибка с параметрами инициализации \n"); // Инициализация клиентской части if (hcSqlCheckInit() < 0) textBox2->AppendText("Ошибка завершения инициализации \n"); // Проверка завершения инициализации err = hcSqlAllocConnect(&pdb); //----------------------------- Создать соединение err = hcSqlConnect(pdb, strConnect, strLogin, strPassword); //Установить связь с СУБД err = hcSqlAllocStmt(pdb, &pOper); // Создать оператор err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (int*)1, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях err = hcSqlExecDirect(pOper, strSql); // Выполняем SQLзапрос err = hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата err = hcSqlRowCount(pOper, &pStr); // Получить количество строк результата err = hcSqlOpenResults(pOper, &pRecSize); // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { char *pNP = infCol[i].fname; dT->Columns->Add(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866))); } //textBox2->AppendText(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866)) + "\r\n"); // отладка char *bufOut = new char[pRecSize]; // Адрес буфера для присылаемых записей. for (long i = 0; i < pStr; i++)//идем по строкам { DataRow ^dR = dT->NewRow();// Добавляем новую строку в виртуальную таблицу err = hcSqlReadResults(pOper, i, bufOut, pRecSize, &cntOut);// Чтение результатов char *p = bufOut; // делаем указатель на буфер for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной //textBox2->AppendText(gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n"); dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866) ); } break; case HSCLI_ET_ARRA: { // 1 Массив байтов заданной длины // textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p) ; } break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p) ; } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p) ; } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p) ; } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p) ; } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len; } dT->Rows->Add(dR); } dataGridView2->DataSource = dT; hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы }//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\\ |
Сообщ.
#146
,
|
|
|
А что ты закомментировал?
|
Сообщ.
#147
,
|
|
|
я когда выкладывал раскоментировал
Добавлено закоментировать опять ? |
Сообщ.
#148
,
|
|
|
Закомментируй обратно, проверь, что долго обрабатывается, и покажи
|
Сообщ.
#149
,
|
|
|
блин принес проект с работы дома не запускается щас смотрю , куча ошибок , студия одна и та же
Добавлено щас разберусь |
Сообщ.
#150
,
|
|
|
Цитата kms @ Помогите пожалуста оптимизировать код до приемлимых скоростей Измерь время выполнения отдельных участков твоих процедур. Попробуй использовать "GetTickCount". После этого можно уже думать. |
Сообщ.
#151
,
|
|
|
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e){ hcERR err; // Код ошибки hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcHSTMT pOper; // Адрес памяти, куда будет записан идентификатор оператора. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации int pCol = 0; // количество колонок hcRECNO pStr = 0; // количество строк unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . unsigned cntOut = 0; // для ф-ции "Чтение результатов" Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. char *strConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text);// Сервер char *strLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox4->Text);// Логин char *strPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox5->Text);// Пароль char *strSql = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox6->Text);// поле SQL if (err = hcSqlInit(&Init) != 0) textBox2->AppendText("Ошибка с параметрами инициализации \n"); // Инициализация клиентской части if (hcSqlCheckInit() < 0) textBox2->AppendText("Ошибка завершения инициализации \n"); // Проверка завершения инициализации err = hcSqlAllocConnect(&pdb); //----------------------------- Создать соединение err = hcSqlConnect(pdb, strConnect, strLogin, strPassword); //Установить связь с СУБД err = hcSqlAllocStmt(pdb, &pOper); // Создать оператор err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (int*)1, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях err = hcSqlExecDirect(pOper, strSql); // Выполняем SQLзапрос err = hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата err = hcSqlRowCount(pOper, &pStr); // Получить количество строк результата err = hcSqlOpenResults(pOper, &pRecSize); // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { char *pNP = infCol[i].fname; dT->Columns->Add(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866))); } //textBox2->AppendText(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866)) + "\r\n"); // отладка char *bufOut = new char[pRecSize]; // Адрес буфера для присылаемых записей. for (long i = 0; i < pStr; i++)//идем по строкам { DataRow ^dR = dT->NewRow();// Добавляем новую строку в виртуальную таблицу err = hcSqlReadResults(pOper, i, bufOut, pRecSize, &cntOut);// Чтение результатов char *p = bufOut; // делаем указатель на буфер /* for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной //textBox2->AppendText(gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n"); dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866) ); } break; case HSCLI_ET_ARRA: { // 1 Массив байтов заданной длины // textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p) ; } break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p) ; } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p) ; } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p) ; } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p) ; } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len; } dT->Rows->Add(dR); */ } dataGridView2->DataSource = dT; hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы }//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\\ 50 сек Добавлено Цитата ЫукпШ @ Измерь время выполнения отдельных участков твоих процедур. Попробуй использовать "GetTickCount". После этого можно уже думать. понял сейчас делаю |
Сообщ.
#152
,
|
|
|
Цитата kms @ DataRow ^dR = dT->NewRow();// Добавляем новую строку в виртуальную таблицу А это ты зачем оставил? |
Сообщ.
#153
,
|
|
|
Цитата Олег М @ закоментить ? А это ты зачем оставил? |
Сообщ.
#154
,
|
|
|
Цитата kms @ закоментить ? Ну да |
Сообщ.
#155
,
|
|
|
35 сек
Добавлено // DataRow ^dR = dT->NewRow();// Добавляем новую строку в виртуальную таблицу 35 сек ___________________________ |
Сообщ.
#156
,
|
|
|
Уже лучше. Теперь закомменть вообще цикл чтения данных
/* for (long i = 0; i < pStr; i++)//идем по строкам { ............................. } */ Код не забудь показать |
Сообщ.
#157
,
|
|
|
//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\\ private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e){ hcERR err; // Код ошибки hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcHSTMT pOper; // Адрес памяти, куда будет записан идентификатор оператора. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации int pCol = 0; // количество колонок hcRECNO pStr = 0; // количество строк unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . unsigned cntOut = 0; // для ф-ции "Чтение результатов" Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. char *strConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text);// Сервер char *strLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox4->Text);// Логин char *strPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox5->Text);// Пароль char *strSql = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox6->Text);// поле SQL if (err = hcSqlInit(&Init) != 0) textBox2->AppendText("Ошибка с параметрами инициализации \n"); // Инициализация клиентской части if (hcSqlCheckInit() < 0) textBox2->AppendText("Ошибка завершения инициализации \n"); // Проверка завершения инициализации err = hcSqlAllocConnect(&pdb); //----------------------------- Создать соединение err = hcSqlConnect(pdb, strConnect, strLogin, strPassword); //Установить связь с СУБД err = hcSqlAllocStmt(pdb, &pOper); // Создать оператор err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (int*)1, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях err = hcSqlExecDirect(pOper, strSql); // Выполняем SQLзапрос err = hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата err = hcSqlRowCount(pOper, &pStr); // Получить количество строк результата err = hcSqlOpenResults(pOper, &pRecSize); // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { char *pNP = infCol[i].fname; dT->Columns->Add(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866))); } //textBox2->AppendText(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866)) + "\r\n"); // отладка char *bufOut = new char[pRecSize]; // Адрес буфера для присылаемых записей. /********************************************************************************* for (long i = 0; i < pStr; i++)//идем по строкам { DataRow ^dR = dT->NewRow();// Добавляем новую строку в виртуальную таблицу err = hcSqlReadResults(pOper, i, bufOut, pRecSize, &cntOut);// Чтение результатов char *p = bufOut; // делаем указатель на буфер for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной //textBox2->AppendText(gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n"); dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866) ); } break; case HSCLI_ET_ARRA: { // 1 Массив байтов заданной длины // textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p) ; } break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p) ; } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p) ; } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p) ; } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p) ; } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len; } dT->Rows->Add(dR); } *********************************************************************************/ dataGridView2->DataSource = dT; hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы }//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\\ ___________________________________________ время выполнения = 2....3 сек ___________________________________________ |
Сообщ.
#158
,
|
|
|
У тебя, кстати, действительно 200тыс строк в таблице?
Добавлено Цитата Олег М @ время выполнения = 2....3 сек Т.е., похоже тромозит hcSqlReadResults Добавлено Посмотри, что возвращается в err и cntOut Добавлено И чему равен pRecSize |
Сообщ.
#159
,
|
|
|
Цитата Олег М @ У тебя, кстати, действительно 200тыс строк в таблице? да точно , Добавлено Цитата Олег М @ Т.е., похоже тромозит hcSqlReadResults Добавлено 10 минут назад Посмотри, что возвращается в err и cntOut Добавлено 9 минут назад И чему равен pRecSize щас один момент делаю |
Сообщ.
#160
,
|
|
|
И вместо err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (int*)1, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях
попробуй всё-таки сделать err = hcSqlSetConnectAttr(pdb, HSCLI_ATTR_FLD_VERBOSE, (void *)1, 0); перед hcSqlConnect(pdb, strConnect, strLogin, strPassword); //Установить связь с СУБД |
Сообщ.
#161
,
|
|
|
Цитата Олег М @ Посмотри, что возвращается в err и cntOut Добавлено 25 минут назад И чему равен pRecSize Прикреплённая картинка
Добавлено Цитата Олег М @ И вместо err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (int*)1, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях попробуй всё-таки сделать err = hcSqlSetConnectAttr(pdb, HSCLI_ATTR_FLD_VERBOSE, (void *)1, 0); перед hcSqlConnect(pdb, strConnect, strLogin, strPassword); //Установить связь с СУБД kmsOnline щас попробую |
Сообщ.
#162
,
|
|
|
Ну, похоже на правду. Хотя, ты вроде говорил о 93-х колонках.
Если hcSqlSetConnectAttr не поможет, то думаю, они там используют hcSqlExecDirectAsync. Но это уже совсем другая история. |
Сообщ.
#163
,
|
|
|
(void*)1 - это прошло
а вот переставить ф-цию нельзя , потому что err = hcSqlAllocStmt(pdb, &pOper); // Создать оператор err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)1, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях Добавлено Цитата Олег М @ Ну, похоже на правду. Хотя, ты вроде говорил о 93-х колонках. Если hcSqlSetConnectAttr не поможет, то думаю, они там используют hcSqlExecDirectAsync. Но это уже совсем другая история. на скрин шоте маленькая табличка , потому что если поставлю на вывод результатов в textBox то до утра не дождусь, поетому и взял маленькую |
Сообщ.
#164
,
|
|
|
Цитата kms @ (void*)1 - это прошло а вот переставить ф-цию нельзя , потому что Нет. Ты посмотри внимательно, что я говорил - закомментарь err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)1, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях - ПЕРЕД hcSqlConnect вставь err = hcSqlSetConnectAttr(pdb, HSCLI_ATTR_FLD_VERBOSE, (void *)1, 0); hcSqlSetConnectAttr!!! Добавлено И код покажи |
Сообщ.
#165
,
|
|
|
Цитата Олег М @ Нет. Ты посмотри внимательно, что я говорил - закомментарь err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)1, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях - ПЕРЕД hcSqlConnect вставь err = hcSqlSetConnectAttr(pdb, HSCLI_ATTR_FLD_VERBOSE, (void *)1, 0); этот вариант не проходит не хочет включать расширенный режим и не получает имена столбиков err = hcSqlAllocConnect(&pdb); //----------------------------- Создать соединение err = hcSqlSetConnectAttr(pdb, HSCLI_ATTR_FLD_VERBOSE, (void*) 1, 0); // ф-ция Изменение параметров соединения Добавлено вот весь код на данный момент //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\\ private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e){ hcERR err; // Код ошибки hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcHSTMT pOper; // Адрес памяти, куда будет записан идентификатор оператора. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации int pCol = 0; // количество колонок hcRECNO pStr = 0; // количество строк unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . unsigned cntOut = 0; // для ф-ции "Чтение результатов" Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. char *strConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text);// Сервер char *strLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox4->Text);// Логин char *strPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox5->Text);// Пароль char *strSql = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox6->Text);// поле SQL if (err = hcSqlInit(&Init) != 0) textBox2->AppendText("Ошибка с параметрами инициализации \n"); // Инициализация клиентской части if (hcSqlCheckInit() < 0) textBox2->AppendText("Ошибка завершения инициализации \n"); // Проверка завершения инициализации err = hcSqlAllocConnect(&pdb); //----------------------------- Создать соединение //err = hcSqlSetConnectAttr(pdb, HSCLI_ATTR_FLD_VERBOSE, (void*) 1, 0); // ф-ция Изменение параметров соединения err = hcSqlConnect(pdb, strConnect, strLogin, strPassword); //Установить связь с СУБД err = hcSqlAllocStmt(pdb, &pOper); // Создать оператор err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)1, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях err = hcSqlExecDirect(pOper, strSql); // Выполняем SQLзапрос err = hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата err = hcSqlRowCount(pOper, &pStr); // Получить количество строк результата err = hcSqlOpenResults(pOper, &pRecSize); // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { //char *pNP = infCol[i].fname; dT->Columns->Add(gcnew String(infCol[i].fname, 0, 32, System::Text::Encoding::GetEncoding(866))); } //textBox2->AppendText(gcnew String(pNP, 0, 32, System::Text::Encoding::GetEncoding(866)) + "\r\n"); // отладка char *bufOut = new char[pRecSize]; // Адрес буфера для присылаемых записей. for (long i = 0; i < pStr; i++)//идем по строкам { err = hcSqlReadResults(pOper, i, bufOut, pRecSize, &cntOut);// Чтение результатов textBox2->AppendText("-------------------------- строка " + i + " ---------------------------------\r\n"); // отладка textBox2->AppendText("pRecSize = " + pRecSize + "\r\n"); // отладка textBox2->AppendText("hcSqlReadResults err = " + err + "\r\n"); // отладка textBox2->AppendText("количество байтов данных, помещённых в буфер пользователя cntOut = " + cntOut + "\r\n"); // отладка textBox2->AppendText("-----------------------------------------------------------------------------------------\r\n"); // отладка char *p = bufOut; // делаем указатель на буфер /********************************************************************************* DataRow ^dR = dT->NewRow();// Добавляем новую строку в виртуальную таблицу for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной //textBox2->AppendText(gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n"); dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866) ); } break; case HSCLI_ET_ARRA: { // 1 Массив байтов заданной длины // textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p) ; } break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p) ; } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p) ; } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p) ; } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p) ; } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len; } dT->Rows->Add(dR); *********************************************************************************/ } dataGridView2->DataSource = dT; hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы }//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\\ |
Сообщ.
#166
,
|
|
|
Цитата kms @ этот вариант не проходит не хочет включать расширенный режим и не получает имена столбиков Тогда забей, верни всё как было. У себя они, похоже пользуются асинхронной выборкой. Добавлено А вообще, замерь-как время, сколько у тебя выполняется до цикла for (long i = 0; i < pStr; i++)//идем по строкам И сколько выполняется этот цикл Добавлено Хотя, ты ж уже писал, что 1-2 сек |
Сообщ.
#167
,
|
|
|
Цитата kms @ вот весь код на данный момент У тебя немного не верный подход вообще к этой проблеме. Создай отдельный класс хотя бы, разнеси функции инициализации и подключения/отключения в конструкторы-деструкторы. Сделать метод какой нибудь ExecuteQuery, туда вынеси саму логику выборки данных. Дальше - все что можно вынести из цикла - выноси. Самые тормозные места - это вычитка из базы и обработка этого всего в цикле. Что пишут в доке? Можно ли ограничить чтение результатов? Например чтоб оно не все данные из БД выбирало, а частями, допустим по 100 записей за раз. Тогда можно избежать цикла, и подгружать данные по мере необходимости, когда пользователь уже до них добрался. Если есть возможность вообще чтение данных убрать из цикла - то это здорово увеличит скорость выполнения. Этот ксласс сделой членом класса своей формы. В каком нибудь обработчике инициализации формы - вызывай функцию инициализации своего класса(коннект к базе установка значений для настроек движка и т.д.). Где нибудь на onClose - вызывай функцию которая закрывает все подключения. А уже в обработчике у тебя должен вызываться только функционал связанный с вычиткой и отображением данных. Сейчас же, у тебя все это отрабатывает по клику на кнопке. Т.е. ткнул кнопку - оно все инициализирует, потом обрабатывает очень долгий коннект, потом читает абсолютно все данные с таблицы, потом все это закрывает. Неудивительно что оно так долго отрабатывает. Зачем коннектится каждый раз, если можно один раз на старте подключиться к базе, и пока программа запущена - с ней работать. |
Сообщ.
#168
,
|
|
|
Цитата Олег М @ У себя они, похоже пользуются асинхронной выборкой. синхронную не нашел еще сделал вот так вроде пару сек выиграл textBox2->AppendText("sizeof(hcSqlDstInfoT) = " + sizeof(hcSqlDstInfoT) + "\r\n"); // отладка for (int i = 0; i < pCol; i++) //получаем столько сколько столбиков { //char *pNP = infCol[i].fname; dT->Columns->Add(gcnew String(infCol[i].fname, 0, 32, System::Text::Encoding::GetEncoding(866))); } |
Сообщ.
#169
,
|
|
|
а мне вот интересно почему ты не используешь SQLite?
|
Сообщ.
#170
,
|
|
|
потом измерил sizeof(hcSqlDstInfoT) и так как размер структуры статика и не изменится ни когда
сделал так #define SIZE_HCSQLDSTINFOT 128 ....... err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * SIZE_HCSQLDSTINFOT, &cntOp);// Получить информацию об операторе . .... Добавлено Цитата Cfon @ а мне вот интересно почему ты не используешь SQLite? при чем тут SQLite, и кто тебе сказал что я не использую , там где уместно я использую SQLite, например в небольших тестах и опросниках, Добавлено Цитата KILLER @ У тебя немного не верный подход вообще к этой проблеме. Создай отдельный класс хотя бы, разнеси функции инициализации и подключения/отключения в конструкторы-деструкторы. Сделать метод какой нибудь ExecuteQuery, туда вынеси саму логику выборки данных. я полностью с тобой согласен , так надо делать я понимаю , но я специально все сделал так на данном этапе что бы удобно было показывать на форуме и не блуждать по всему проекту, т.е. на данном этапе это как бы стендовая конструкция , чтобы линейно просмотреть все понять саму логику подключения запроса и обработки ответа от сервера, т.е. весь цикл работы клиента с SQL-сервером на примере СУБД HyTech, почему выбрал именно ее - потому что русская , простая как самокат, шустрая на больших объемах данных, да и просто попалась под руку Добавлено Цитата KILLER @ Что пишут в доке? Можно ли ограничить чтение результатов? Например чтоб оно не все данные из БД выбирало, а частями, допустим по 100 записей за раз. перечитываю док , вот что сказано как раз про ф-цию которой читаем hcERR hcSqlReadResults( hcHSTMT h, /* Оператор с результатами */ hcRECNO gStart, /* С какой записи начинаем читать */ void *pBuf, unsigned wBufSize, unsigned *cnt) /* Сколько прочитали */ Параметры: ТипАргументЗначение hcHSTMT h Идентификатор оператора, содержащего результаты поиска оператором select. hcRECNO gStart Номер записи в результате, начиная с которой пересылаются результаты. Все найденные записи нумеруются с 0. void * pBuf Адрес буфера для присылаемых записей. unsigned wBufSize Размер буфера для результатов. В буфер помещается целое количество записей. Если запись не может войти в буфер целиком, она не присылается. unsigned * cnt Адрес, куда функция запишет количество байтов данных, помещённых в буфер пользователя. Если это количество разделить на длину записи, то получим количество считанных записей. Неполные записи не присылаются. т.е. как бы можно задать прочитать с какой позиции по какую , и зная количество строк можно задавать по сколько выбирать , но опять же что можно кроме цикла, если в курсе как реализовать подскажи |
Сообщ.
#171
,
|
|
|
Цитата KILLER @ Если есть возможность вообще чтение данных убрать из цикла - то это здорово увеличит скорость выполнения. вот если это реализовать будет счастье , только не представляю как ??? в доке http://hytechdb.ru/index.php?s=docs&ru=V25...li/txt_func.htm вроде смотрю не могу не какой ф-ции подходящей найти, буду думать , если че прийдет на ум подскажите , еслибы как то задавать в функцию чтобы летела пачка на тыщ 100 200 или там 500 000 строк и раз эту пачку сразу в DataTable , например вот так DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу dataGridView2->DataSource = пачка(500000строк); вот это было бы класс, но в каждой шутке есть доля шутки |
Сообщ.
#172
,
|
|
|
а почему ты не используешь MFC?
|
Сообщ.
#173
,
|
|
|
Цитата Cfon @ а почему ты не используешь MFC а это даст скорость ? если да то помоги |
Сообщ.
#174
,
|
|
|
Цитата kms @ Цитата Cfon @ а почему ты не используешь MFC а это даст скорость ? если да то помоги ты не ответил на мой вопрос |
Сообщ.
#175
,
|
|
|
Цитата kms @ при чем тут SQLite, и кто тебе сказал что я не использую , там где уместно я использую SQLite, например в небольших тестах и опросниках, Даже представить боюсь, как ты её используешь Добавлено Цитата kms @ вот это было бы класс, но в каждой шутке есть доля шутки То, что у тебя запрос вычитывается минуту, это нормально. Для интерфейса просто нужно чтоб это происходило в другом потоке. Тогда первые данные появятся сразу, остальные постепенно |
Сообщ.
#176
,
|
|
|
Цитата Олег М @ Даже представить боюсь, как ты её используешь например так string databaseName = Directory.GetCurrentDirectory() + "\\Anketa.db"; SQLiteConnection connection = new SQLiteConnection(string.Format("Data Source={0};", databaseName)); connection.Open(); SQLiteCommand command = new SQLiteCommand("SELECT MAX(NomAnket) FROM 'Anketa' WHERE Podrazdelenie = '" + comboBox1.Text.ToString() + "' ;", connection); SQLiteDataReader reader = command.ExecuteReader(); Цитата Олег М @ То, что у тебя запрос вычитывается минуту, это нормально. но у родной консольки написанной на Делфях это все происходит за 1сек и даже меньше с учетом того что конек не локально а сетевой Цитата Олег М @ Для интерфейса просто нужно чтоб это происходило в другом потоке. Тогда первые данные появятся сразу, остальные постепенно а как это реализовать подскажи |
Сообщ.
#177
,
|
|
|
Цитата kms @ а как это реализовать подскажи Ты с потоками знаком, _beginthreadex? |
Сообщ.
#178
,
|
|
|
Цитата kms @ еслибы как то задавать в функцию чтобы летела пачка на тыщ 100 200 или там 500 000 строк и раз эту пачку сразу в DataTable , например вот так Нет, так не правильно делать. Во первых у тебя все зависнет на полчаса при вычитке и пересылке 100 - 500 тыщ записей, во вторых ты по памяти очень сильно просядешь. Нужно вычитывать небольшими порциями, например - hcSqlReadResults, принимает с какой записи начинаем читать, и сколько прочитать. Лучше вычитывать порциями, ну например по 50-100 записей за 1 раз, и показывать это пользователю, если он начинает мотать таблицу вниз, мы по мере необходимости подгружаем записи, плюс это можно реализовать с помощью многопоточности, тогда все это будет подгружаться в фоне, по мере надобности. Добавлено Да, и судя по всему hcSqlReadResults можно вынести из цикла и заставить ее читать сразу пачку записей, а не в цикле по одной, по крайней мере так в доке написано: Цитата unsigned wBufSize Размер буфера для результатов. В буфер помещается целое количество записей. Если запись не может войти в буфер целиком, она не присылается. Только нужно указать позицию, с которой нужно читать и размер буфера сделать побольше. Добавлено Можно при инициализации вычитывать например сразу 50-100 записей и показывать их, потом сделать обработчик события у сетки, например на какой нибудь OnScroll, и в этом обработчике проверять, если пользователь например мотает вниз и домотал до 80 записи, то подгрузить следующие 50-100 записей. Тогда данные будут подгружаться по мере необходимости, ну и шустрее будет работать. |
Сообщ.
#179
,
|
|
|
Цитата kms @ т.е. на данном этапе это как бы стендовая конструкция , чтобы линейно просмотреть все понять саму логику подключения запроса и обработки ответа от сервера Ну так у тебя заработал твой клик по кнопке, теперь ты говоришь скорость важна. Ну так самое время разносить все это по классам. |
Сообщ.
#180
,
|
|
|
Цитата Олег М @ Ты с потоками знаком, _beginthreadex? слабо Цитата KILLER @ Да, и судя по всему hcSqlReadResults можно вынести из цикла и заставить ее читать сразу пачку записей, а не в цикле по одной, по крайней мере так в доке написано: сейчас пробую Цитата KILLER @ Ну так у тебя заработал твой клик по кнопке, теперь ты говоришь скорость важна. Ну так самое время разносить все это по классам. ОК тоже щас займус |
Сообщ.
#181
,
|
|
|
Цитата KILLER @ Да, и судя по всему hcSqlReadResults можно вынести из цикла и заставить ее читать сразу пачку записей, а не в цикле по одной, по крайней мере так в доке написано: да точно , попробовал вынес ф-цию hcSqlReadResults за цикл ..... char *bufOut = new char[pRecSize]; // Адрес буфера для присылаемых записей. err = hcSqlReadResults(pOper, 0, bufOut, pRecSize, &cntOut);// Чтение результатов char *p = bufOut; // делаем указатель на буфер for (long i = 0; i < pStr; i++) //идем по строкам { DataRow ^dR = dT->NewRow(); // Добавляем новую строку в виртуальную таблицу for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: // 0 Массив символов длиной не более заданной dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866) ); break; . . ....... читает , но вот что получается , при чтении таблицы все колонки с русскими буквами вываливает ошибку Необработанное исключение типа "System.DivideByZeroException" в RudderHyTech.exe Дополнительные сведения: Попытка деления на нуль. а при чтении небольшой таблицы с одним текстовым полем выводит без ошибок , но и символы поплыли т.е. такое ощущение что выводит данные не с тех участков а что интересней первая строка выводит правильно Прикреплённая картинка
|
Сообщ.
#182
,
|
|
|
тут
for (long i = 0; i < pStr; i++) //идем по строкам { DataRow ^dR = dT->NewRow(); // Добавляем новую строку в виртуальную таблицу for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type) // в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной textBox2->AppendText("infCol[j].len" + infCol[j].len + "\r\n"); dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)); } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины // dR[j] = *reinterpret_cast<unsigned char *>(p) ; break; case HSCLI_ET_BYTE: // 2 Элемент - unsigned char (короткое целое) short dR[j] = *reinterpret_cast<unsigned char *>(p); break; case HSCLI_ET_INTR: // 3 Элемент - signed short dR[j] = *reinterpret_cast<signed short *>(p); break; case HSCLI_ET_WORD: // 4 Элемент - unsigned short dR[j] = *reinterpret_cast<unsigned short *>(p); break; case HSCLI_ET_DATE: // 5 Дата - unsigned short dR[j] = *reinterpret_cast<unsigned short *>(p); break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: //7 Элемент - long int dR[j] = *reinterpret_cast<long int *>(p); break; case HSCLI_ET_DWRD: // 8 Элемент - unsigned long int в БД это dword dR[j] = *reinterpret_cast<unsigned long int *>(p); break; case HSCLI_ET_FLOA: { // 9 Элемент - float dR[j] = *reinterpret_cast<float *>(p); break; case HSCLI_ET_CURR: { // 10 Деньги (double) dR[j] = *reinterpret_cast<double *>(p); break; case HSCLI_ET_DFLT: { // 11 Элемент - double dR[j] = *reinterpret_cast<double *>(p); break; case HSCLI_ET_QINT: // 12 Элемент - signed __int64 dR[j] = *reinterpret_cast<signed __int64 *>(p); break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 dR[j] = *reinterpret_cast<unsigned __int64 *>(p); break; p += infCol[j].len; } dT->Rows->Add(dR); } я так понимаю надо сдвигать p += infCol[j].len; |
Сообщ.
#183
,
|
|
|
Цитата kms @ я так понимаю надо сдвигать p += infCol[j].len; как то по другому Нет, конечно. Там надо выделить буфер достаточного размера, передает его и его размер в hcSqlReadResults и осмотреть, что вернулось. Сейчас ты выделяешь буфер только под одну запись, тебе она и возвращается |
Сообщ.
#184
,
|
|
|
нет оказалось сдвиг нормальный
просто увеличил буфер на количество строк char *bufOut = new char[pRecSize * pStr]; // Адрес буфера для присылаемых записей. err = hcSqlReadResults(pOper, 0, bufOut, pRecSize * pStr, &cntOut);// Чтение результатов и количество читаемых байтов тоже на кол-во строк |
Сообщ.
#185
,
|
|
|
тут теперь другая проблема
буфер выделил нормальный , а вот считывается все равно мало , на маленьких таблицах нормально , а вот большие (200000х93) выводит только 13 строк , а потом всякий мусор Прикреплённая картинка
Добавлено сделал пока так ..... for (long i = 0; i < cntOut / pRecSize; i++) //идем по строкам количества считанных записей { ..... теперь как бы вписать hcSqlReadResults(pOper, 0, bufOut, pRecSize * pStr , &cntOut);// Чтение результатов что бы вычитывать оставшиеся записи т.е. следующую партию записей Добавлено Цитата Олег М @ Там надо выделить буфер достаточного размера, передает его и его размер в hcSqlReadResults и осмотреть, что вернулось. hcSqlGetStmtAttr err=0 hcSqlReadResults err= 0 hcSqlReadResults pRecSize= 2034 количество байтов данных, помещённых в буфер пользователя cntOut= 38646 pRecSize * pStr= 39492144 количество считанных записей cntOut / pRecSize = 19 |
Сообщ.
#186
,
|
|
|
пробую делать так
..... for (long i = 0; i < pStr; i++) //идем по строкам { if ( nomRec != pStr) // если кол-во считанных записей не совпадает с кол-вом строк { i += nomRec - 1 ; err = hcSqlReadResults(pOper, i, bufOut, pRecSize * nomRec, &cntOut);// Чтение результатов } ...... но что то тут не так , все равно выводится 19строк а остальные мусор |
Сообщ.
#187
,
|
|
|
Как же так сейчас попробовал табличку на стандартной "HyTech Explorer" 143 000 000 строк 6 столбцов , 2сек вывелось ,
как бы хоть примерно сделать чтобы хоть приблизится к такому результату |
Сообщ.
#188
,
|
|
|
Подозреваю, через 2 сек отображаются первые пара десятков записей. Чтобы увидеть последнюю, понадобится много больше времени.
|
Сообщ.
#189
,
|
|
|
Цитата Олег М @ Подозреваю, через 2 сек отображаются первые пара десятков записей. Чтобы увидеть последнюю, понадобится много больше времени. не не , как только показывается записи я сразу же прокуручиваю за 1 сек вниз и вижу последние строки данные |
Сообщ.
#190
,
|
|
|
вообщем сейчас вот так только скорость такая же 25сек
char *bufOut = new char[pRecSize * pStr]; // Адрес буфера для присылаемых записей. long nZ = 0; for(;;) { unsigned cntOut = 0; err = hcSqlReadResults(pOper, nZ, bufOut, pRecSize * pStr, &cntOut);// Чтение результатов if(cntOut == 0) break; int nomRec = cntOut / pRecSize; char *p = bufOut; // делаем указатель на буфер for (long i = 0; i < nomRec; i++) //идем по строкам { DataRow ^dR = dT->NewRow(); // Добавляем новую строку в виртуальную таблицу for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type) {...} p += infCol[j].len; } dT->Rows->Add(dR); } nZ = nZ + nomRec; } |
Сообщ.
#191
,
|
|
|
Цитата kms @ вообщем сейчас вот так только скорость такая же 25сек Уже на что-то похоже, в смысле код. 1-е Проверяй err - if(cntOut == 0 || err != 0) break; 2-e Убери все обращения к dT: DataRow ^dR = dT->NewRow(); dT->Rows->Add(dR); и т.д. и замерь время |
Сообщ.
#192
,
|
|
|
пытаюсь выбрать таблицу на 5 000 000 строк 10 полей выбело ошибку нехватка памяти через 8мин , и скушала 4 Гб ОЗУ,
в дебаге смотрю дошло только до nZ = 843642 Добавлено Цитата Олег М @ 1-е Проверяй err - if(cntOut == 0 || err != 0) break; 2-e Убери все обращения к dT: DataRow ^dR = dT->NewRow(); dT->Rows->Add(dR); и т.д. и замерь время ОК делаю Добавлено ну вот как то так все сделал как ты сказал Старт 20.03.2017 15:57:46 Финишь 20.03.2017 15:58:09 Время выполнения for(;;) 00:00:22.9850000 |
Сообщ.
#193
,
|
|
|
Цитата kms @ у вот как то так все сделал как ты сказал Сколько записей должно было вернуться? И покажи код |
Сообщ.
#194
,
|
|
|
Цитата kms @ не не , как только показывается записи я сразу же прокуручиваю за 1 сек вниз и вижу последние строки данные Да да да, за 1 секунду проматываешь 143 миллиона записей. Да еще это все за 2 секунды вычитывает из базы. Ты себе представляешь вообще хотя бы теоретически это число? Я нет. Ну порой просто портянку текста мотаешь минут 5, чтоб до конца сайта дойти, а ты 143 миллиона записей за 1 секунду в низ? У тебя подгрузились первые 10 записей, как тебе выше сказали, ты мотанул вниз до предела, тебе загрузились последние 10 записей. Ок, давай я тебе на пальцах объясню: Вот ты говоришь что есть у тебя 143 миллиона строчек, 6 столбцев. Смотри, пусть каждая запись(строчка) занимает 54 символа, как ты выше приводил, т.е. в каждой строчке, в каждой колонке по 9 символов. У нас 143 000 000 записей, это значит вся база у нас весит 143 000 000 * 54 = 7 722 000 000 байт, если это число поделить на 1024 получим размер в киллобайтах - 7 541 015 КБ / 1024 = 7364 МБ / 1024 = ~7 TB у тебя весит только база, т.е. 7 терабайт у тебя загрузилось за 2 секунды, висит в памяти и отображается? Предполагаю, что на том компе, на котором ты смотришь результаты, у тебя и половины памяти нет от размера базы, причем не оперативной, а вообще всей которая существует. Не веришь мне - посчитай сам на пальцах. Цитата kms @ как бы хоть примерно сделать чтобы хоть приблизится к такому результату Подгружать по 50 записей и показывать их. Именно так они и делают у себя. Никто в своем уме не станет вычитывать все данные из БД. |
Сообщ.
#195
,
|
|
|
например вот вот этот участок
case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной DateTime s1 = DateTime::Now; // отладка textBox2->AppendText(gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n");// отладка DateTime s2 = DateTime::Now; // отладка textBox2->AppendText("Время выполнения " + (s2-s1).ToString() + "\r\n");// отладка //dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)); } break; выполняется вот за такое время , я понимаю что это так на вскидку , и приблизительно , но все же qweasdzxcrty Время выполнения 00:00:00.0150000 qweasdzxcrty Время выполнения 00:00:00 qweasdfghrt Время выполнения 00:00:00.0020000 qweasd Время выполнения 00:00:00.0010000 qweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcr Время выполнения 00:00:00.0020000 qweasdzxcrty Время выполнения 00:00:00.0020000 qweasdzxcrty Время выполнения 00:00:00.0020000 qweasdfghrt Время выполнения 00:00:00.0020000 qweasd Время выполнения 00:00:00.0020000 qweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcr Время выполнения 00:00:00.0030000 qweasdzxcrty Время выполнения 00:00:00.0020000 qweasdzxcrty Время выполнения 00:00:00.0010000 qweasdfghrt Время выполнения 00:00:00.0010000 qweasd Время выполнения 00:00:00.0010000 qweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcr Время выполнения 00:00:00.0020000 qweasdzxcrty Время выполнения 00:00:00.0020000 qweasdzxcrty Время выполнения 00:00:00.0020000 qweasdfghrt Время выполнения 00:00:00.0010000 qweasd Время выполнения 00:00:00.0020000 qweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcr Время выполнения 00:00:00.0030000 qweasdzxcrty Время выполнения 00:00:00.0020000 qweasdzxcrty Время выполнения 00:00:00.0030000 qweasdfghrt Время выполнения 00:00:00.0020000 qweasd Время выполнения 00:00:00.0010000 qweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcr Время выполнения 00:00:00.0030000 qweasdzxcrty Время выполнения 00:00:00.0020000 qweasdzxcrty Время выполнения 00:00:00.0030000 qweasdfghrt Время выполнения 00:00:00.0020000 qweasd Время выполнения 00:00:00.0010000 qweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcr Время выполнения 00:00:00.0020000 qweasdzxcrty Время выполнения 00:00:00.0020000 qweasdzxcrty Время выполнения 00:00:00.0010000 qweasdfghrt Время выполнения 00:00:00.0030000 qweasd Время выполнения 00:00:00.0030000 qweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcr Время выполнения 00:00:00.0040000 qweasdzxcrty Время выполнения 00:00:00.0030000 qweasdzxcrty Время выполнения 00:00:00.0030000 qweasdfghrt Время выполнения 00:00:00.0060000 qweasd Время выполнения 00:00:00.0020000 qweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcr Время выполнения 00:00:00.0020000 qweasdzxcrty Время выполнения 00:00:00.0020000 qweasdzxcrty Время выполнения 00:00:00.0020000 qweasdfghrt Время выполнения 00:00:00.0020000 qweasd Время выполнения 00:00:00.0020000 qweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcr Время выполнения 00:00:00.0030000 qweasdzxcrty Время выполнения 00:00:00.0020000 qweasdzxcrty Время выполнения 00:00:00.0010000 qweasdfghrt Время выполнения 00:00:00.0020000 qweasd Время выполнения 00:00:00.0010000 qweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcrqweasdzxcr Время выполнения 00:00:00.0030000 йцувапмит Время выполнения 00:00:00.0020000 щшщзнгшролить Время выполнения 00:00:00.0020000 фывйцуячсап Время выполнения 00:00:00.0010000 джэрол Время выполнения 00:00:00.0020000 йцуфывячскенапрмитгшщолдщзхлджэъбютимсчяфывапролджэ Время выполнения 00:00:00.0020000 йцувапмит Время выполнения 00:00:00.0020000 щшщзнгшролить Время выполнения 00:00:00.0020000 фывйцуячсап Время выполнения 00:00:00.0020000 джэрол Время выполнения 00:00:00.0020000 йцуфывячскенапрмитгшщолдщзхлджэъбютимсчяфывапролджэ Время выполнения 00:00:00.0020000 йцувапмит Время выполнения 00:00:00.0020000 щшщзнгшролить Время выполнения 00:00:00.0020000 фывйцуячсап Время выполнения 00:00:00.0010000 джэрол Время выполнения 00:00:00.0020000 йцуфывячскенапрмитгшщолдщзхлджэъбютимсчяфывапролджэ Время выполнения 00:00:00.0020000 йцувапмит Время выполнения 00:00:00.0010000 щшщзнгшролить Время выполнения 00:00:00.0010000 фывйцуячсап Время выполнения 00:00:00.0010000 джэрол Время выполнения 00:00:00.0010000 йцуфывячскенапрмитгшщолдщзхлджэъбютимсчяфывапролджэ Время выполнения 00:00:00.0020000 йцувапмит Время выполнения 00:00:00.0020000 щшщзнгшролить Время выполнения 00:00:00.0030000 фывйцуячсап Время выполнения 00:00:00.0020000 джэрол Время выполнения 00:00:00.0010000 йцуфывячскенапрмитгшщолдщзхлджэъбютимсчяфывапролджэ Время выполнения 00:00:00.0020000 йцувапмит Время выполнения 00:00:00.0010000 щшщзнгшролить Время выполнения 00:00:00.0010000 фывйцуячсап Время выполнения 00:00:00.0010000 джэрол Время выполнения 00:00:00.0010000 йцуфывячскенапрмитгшщолдщзхлджэъбютимсчяфывапролджэ Время выполнения 00:00:00.0030000 йцувапмит Время выполнения 00:00:00.0020000 щшщзнгшролить Время выполнения 00:00:00.0030000 фывйцуячсап Время выполнения 00:00:00.0020000 джэрол Время выполнения 00:00:00.0020000 йцуфывячскенапрмитгшщолдщзхлджэъбютимсчяфывапролджэ Время выполнения 00:00:00.0020000 йцувапмит Время выполнения 00:00:00.0010000 щшщзнгшролить Время выполнения 00:00:00.0020000 фывйцуячсап Время выполнения 00:00:00.0030000 джэрол Время выполнения 00:00:00.0020000 йцуфывячскенапрмитгшщолдщзхлджэъбютимсчяфывапролджэ Время выполнения 00:00:00.0040000 йцувапмит Время выполнения 00:00:00.0030000 щшщзнгшролить Время выполнения 00:00:00.0020000 фывйцуячсап Время выполнения 00:00:00.0030000 джэрол Время выполнения 00:00:00.0030000 йцуфывячскенапрмитгшщолдщзхлджэъбютимсчяфывапролджэ Время выполнения 00:00:00.0030000 йцувапмит Время выполнения 00:00:00.0020000 щшщзнгшролить Время выполнения 00:00:00.0020000 фывйцуячсап Время выполнения 00:00:00.0010000 джэрол Время выполнения 00:00:00.0010000 йцуфывячскенапрмитгшщолдщзхлджэъбютимсчяфывапролджэ Время выполнения 00:00:00.0020000 |
Сообщ.
#196
,
|
|
|
Цитата kms @ вообщем сейчас вот так только скорость такая же 25сек Ну так все правильно, у тебя ведь в цикле вызывается hcSqlReadResults. Тебе эту функцию вообще нужно убрать из цикла, из любого цикла, она в принципе не должна находится в цикле. Она должна читать пачку записей, ровно 1 раз когда нужно. |
Сообщ.
#197
,
|
|
|
Цитата Олег М @ Сколько записей должно было вернуться? И покажи код щас Цитата KILLER @ Да да да, за 1 секунду проматываешь 143 миллиона записей. Да еще это все за 2 секунды вычитывает из базы. Ты себе представляешь вообще хотя бы теоретически это число? Я нет. Ну порой просто портянку текста мотаешь минут 5, чтоб до конца сайта дойти, а ты 143 миллиона записей за 1 секунду в низ? У тебя подгрузились первые 10 записей, как тебе выше сказали, ты мотанул вниз до предела, тебе загрузились последние 10 записей. Ок, давай я тебе на пальцах объясню: Вот ты говоришь что есть у тебя 143 миллиона строчек, 6 столбцев. Смотри, пусть каждая запись(строчка) занимает 54 символа, как ты выше приводил, т.е. в каждой строчке, в каждой колонке по 9 символов. У нас 143 000 000 записей, это значит вся база у нас весит 143 000 000 * 54 = 7 722 000 000 байт, если это число поделить на 1024 получим размер в киллобайтах - 7 541 015 КБ / 1024 = 7364 МБ / 1024 = ~7 TB у тебя весит только база, т.е. 7 терабайт у тебя загрузилось за 2 секунды, висит в памяти и отображается? Предполагаю, что на том компе, на котором ты смотришь результаты, у тебя и половины памяти нет от размера базы, причем не оперативной, а вообще всей которая существует. Не веришь мне - посчитай сам на пальцах. я все прекрасно понимаю, но тем не менее, одна эта таблица в БД весит всего 4Гб в ней 140 000 000 это не такое уж большое число для больших БД, потом чтобы не быть голословным , могу записать на видео рабочий стол и выложить вам посмотрите |
Сообщ.
#198
,
|
|
|
Сообщ.
#199
,
|
|
|
Цитата kms @ я все прекрасно понимаю, но тем не менее, одна эта таблица в БД весит всего 4Гб в ней 140 000 000 это не такое уж большое число для больших и БД, потом чтобы не быть голословных , могу записать на видео рабочий стол и выложить вам посмотрите Нет, ты плохо понимаешь как оно работает. Даже если база весит 2 гигабайта, нет никакого смысла ее всю читать в память. Я тебе уже 4 раза написал, что нужно сделать, чтоб добиться ускорения с 25 сек до 1-2 сек. Ты даже со мной согласился, а сейчас уже 5 - ю страницу делаешь ровно то же самое, что и в самом начале темы. В каком то цикле, вычитываешь всю таблицу из базы, заполняешь ей что то там. Да хоть как ты не изгаляйся не сможешь ты сделать так, как они сделали. ПОтому что они сделали так, как правильно, а ты ерундой занимаешься. Нет чтоб делать как тебе говорят, придумываешь свои странные идеи. У тебя код уже должен был превратится хотя бы в простенький класс, с разнесенной логикой, с отдельной функцией вычитки. А ты все еще возишься с кликом, и меняешь условия цикла, чтоб выиграть десятые доли секунд, вместо того, чтоб убрать слона с дороги на обочину. Добавлено Цитата kms @ вот тут время выполнения запроса и количество полученных строк И что? Такое практически по всем вьюверах можно наблюдать. Вот у меня на работе на прошлой, были запросы, которые возвращали данных больше чем у меня памяти в компе, и тоже можно было на конец перемотать и посмотреть ИД последней записи. И что? Они работают соверешенно по другому, не так, как ты себе представляешь. Создают обычный кещь на 100-150 записей, и показывают их тебе, все что ты не видишь - оно и не грузиться. |
Сообщ.
#200
,
|
|
|
Цитата KILLER @ Да хоть как ты не изгаляйся не сможешь ты сделать так, как они сделали. ПОтому что они сделали так, как правильно, а ты ерундой занимаешься. прекрасно понимаю , надо брать привязывать к прокрутке подгрузку пачки из запроса но как это реализовать в теории я еще пол года буду сам долбится , |
Сообщ.
#201
,
|
|
|
Цитата kms @ прекрасно понимаю , надо брать привязывать к прокрутке подгрузку пачки из запроса но как это реализовать в теории я еще пол года буду сам долбится , Еслиб ты прекрасно понимал, у тебя уже цикла бы не было. Сделай сначало вычитку 50-100 записей, чтоб оно работало. Затем создай кнопку другую, и в ее обработчике дойбейся чтоб при нажатии грузило еще по 50-100 записей, хотя бы так. Потом уже перейдем к непосредственно реализации локального кеша, чтоб пока ты до конца не прочитал память не кончилась. |
Сообщ.
#202
,
|
|
|
Цитата KILLER @ В каком то цикле, вычитываешь всю таблицу из базы, заполняешь ей что то там. ОК , если не вычитывать все , а только какую то порцию и гнать ее сразу через DataTable в dataGridView так получается ? Добавлено Цитата KILLER @ Сделай сначало вычитку 50-100 записей, чтоб оно работало. Затем создай кнопку другую, и в ее обработчике дойбейся чтоб при нажатии грузило еще по 50-100 записей, хотя бы так. Потом уже перейдем к непосредственно реализации локального кеша, чтоб пока ты до конца не прочитал память не кончилась. ОК делаю |
Сообщ.
#203
,
|
|
|
Цитата kms @ ОК , если не вычитывать все , а только какую то порцию и гнать ее сразу через DataTable в dataGridView так получается ? Примерно так. Но раз у тебя ГУЙ основан на WinForms или что там? WPF, то все будет немного по другому. По хорошему тебе нужно инкапсулировать(скрыть) свою работу с БД в отдельном С++ классе, не С++/CLI как сейчас у тебя, а именно отдельный С++ класс, можно его сделать например отдельным проектом в виде DLL, дальше сделать для него оболочку на C++/CLI(хотя можно и на C++/CLI сделать класс сразу с вычиткой из БД, но это будет не совсем правильно). После этого, у себя в WPF на C# например ты используешь BindingList например для связи вычитанных данных и таблицы. И тебе вообще не нужно будет заморачиваться с тем, с чем ты сейчас морочаешься. У тебя очень сильно упростится и укоротится код и так будет правильнее. Как работать с биндингами и с БД из C#, можно например почитать тут: http://www.c-sharpcorner.com/UploadFile/71...iew-in-ado-net/ Или вот еще: https://msdn.microsoft.com/ru-ru/library/fb...(v=vs.110).aspx Но пока с этим не торопись. Для начала добейся стабильной вычитки данных порциями по 50-100 записей по клику на кнопке. И измерь время выполнения такого кода. По идее оно будет в районе 1-2 сек, если сделать все правильно, возможно и меньше. Добавлено По поводу подгрузки данных в C# в гриде, по мере прокрутки ползунка, уже и это все есть, осталось только заюзать, например вот - https://msdn.microsoft.com/ru-ru/library/ms...(v=vs.110).aspx Добавлено Т.е. по сути тебе осталось вынести всю работу с базой данных в отдельный класс, остальное уже все за тебя написано. |
Сообщ.
#204
,
|
|
|
Цитата kms @ вот тут время выполнения запроса и количество полученных строк Ни одна программа в жизни не загрузит 140 мил за раз А то что там указано 140 мил так это простой SQL запрос SELECT COUNT(*) FROM TABLE |
Сообщ.
#205
,
|
|
|
Цитата KILLER @ Сделай сначало вычитку 50-100 записей, ты был совершенно прав , я методом тыка вычислил что при скролинге у них подгружается по 40 - 50 записей в ДатаГрид (на тормазнутой тачке хорошо виден этот момент) Добавлено Цитата KILLER @ Примерно так. Но раз у тебя ГУЙ основан на WinForms или что там? WPF, Сейчас у меня проект MSVS2015C++CLR на WinForms, а потом когда что нибудь получится, пробывать на C#WPF Добавлено Цитата KILLER @ Но пока с этим не торопись. Для начала добейся стабильной вычитки данных порциями по 50-100 записей по клику на кнопке. И измерь время выполнения такого кода. По идее оно будет в районе 1-2 сек, если сделать все правильно, возможно и меньше. да да понял, сейчас это и долблю Добавлено Цитата Cfon @ А то что там указано 140 мил так это простой SQL запрос SELECT COUNT(*) FROM TABLE нет , там функция возращает количество и строк и колонок , err = hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата err = hcSqlRowCount(pOper, &pStr ); // Получить количество строк результата |
Сообщ.
#206
,
|
|
|
а эта функция что делает? считывает 140 мил строк подсчитывает и возвращает результат?
|
Сообщ.
#207
,
|
|
|
Цитата Cfon @ а эта функция что делает? считывает 140 мил строк подсчитывает и возвращает результат? ну тут я уж не знаю , потому что она в dll-ке , и сама СУБД HyTech где то проскакивало сообщение что она вообще задумывалась как NoSQL и первые версии так и были , (сама СУБД на инвертированных списках)поетому можно только гадать че там, есть желание открой dll-ку и посмотри че там SQl или че то другое Добавлено Цитата KILLER @ Еслиб ты прекрасно понимал, у тебя уже цикла бы не было. а как без цикла ??? ф-ция hcSqlReadResults(pOper, nZ, bufOut, pRecSize, &cntOut);// Чтение результатов помещает в буфер bufOut столько записей сколько сама захочет , и это не зависит от предоставляемого размера буфера, т.е. если ставлю большой буфер она все равно возращает свое количество строк как она расчитывает бог его знает может как то строка количество полей , вот и еще на вход то надо подать размер буфера если мало ошибка если много ошибка, как высчитать сколько ей надо , вот и как же без цикла например я подаю в эту ф-цию буфер на вскидки для 100 строк , а она мне возращает только 19записей я эти 19записей вывел запомнил позицию сколько вывел и дальше мне что как ??? |
Сообщ.
#208
,
|
|
|
Цитата kms @ помещает в буфер bufOut столько записей сколько сама захочет , и это не зависит от предоставляемого размера буфера, т.е. если ставлю большой буфер она все равно возращает свое количество строк как она расчитывает бог его знает может как то строка количество полей , вот и еще на вход то надо подать размер буфера если мало ошибка если много ошибка, как высчитать сколько ей надо , Если верить доке, то эта функция: Цитата hcERR hcSqlReadResults( hcHSTMT h, /* Оператор с результатами */ hcRECNO gStart, /* С какой записи начинаем читать */ void *pBuf, unsigned wBufSize, /*Размер буфера для результатов. В буфер помещается целое количество записей. Если запись не может войти в буфер целиком, она не присылается. */ unsigned *cnt) /* Сколько прочитали */ Так вот - gStart - с какой записи читаем, например с 5-й или 100-ой. pBuf - указатель на буфер wBufSize - Размер буфера В твоем случае pRecSize возвращается из hcSqlOpenResults, на сколько я понимаю, оно просто возвращает размер самой большой записи. Соответственно твой пример приобразуется в какой то такой: const int gc_ReadMaxRecords = 100; /*Вычитывать по 100 записей за раз*/ unsigned char* bufOut = new unsigned char[pRecSize * gc_ReadMaxRecords]; hcSqlReadResults(pOper, nZ, bufOut, pRecSize*gc_ReadMaxRecords, &cntOut); По идее такой пример будет вычитывать сразу 100 записей за 1 раз. Сколько оно реально вычитало, можно посмотреть в cntOut, после вызова этой функции. |
Сообщ.
#209
,
|
|
|
начну опять по порядку
1) какойбы я не ставил размер буфера ф-ция все равно записывает столько сколько хочет, экспериментально вывел что 10 записей она вычитывает точно на всех таблицах , единственное что заметил , зависит от размера полей , а длина всей строки получается это сумма всех полей, это само сабой 2) потом вычитал я например сейчас 10 записей это массив байтов , и теперь что бы не обращаясь к ф-ции hcSqlReadResults надо как то распарсить этот массив байтов, либо hcSqlReadResults в цикл и по строчкам вычитывать и каждую строку парсить в отдельности как это сейчас и сделанно Добавлено Цитата KILLER @ По идее такой пример будет вычитывать сразу 100 записей за 1 раз. Сколько оно реально вычитало, можно посмотреть в cntOut, после вызова этой функции. не хочет ф-ция за один раз вычитывать 100 записей не на одной таблице Добавлено Цитата KILLER @ В твоем случае pRecSize возвращается из hcSqlOpenResults, на сколько я понимаю, оно просто возвращает размер самой большой записи. нет не самой большой, запись это в нашем понимании строка, ее длина одинакова у всех строк текущей выборки, или как можно сказать в текущем операторе |
Сообщ.
#210
,
|
|
|
Цитата Олег М @ совсем запарился , И покажи код на данный момент вот что получается , по нажатию кнопки запрос идет на все таблицу в почти 5млн строк, но выводится в датаГрид только около 100 , точно ни когда не будет , ближайшее число после сотни на котором мы выходим из цикла private: System::Void toolStripButton5_Click(System::Object^ sender, System::EventArgs^ e) { #define SIZE_HCSQLDSTINFOT 128 DateTime tT1, tT2, tT3, tT4 , tT5; tT1 = DateTime::Now; textBox2->AppendText("Старт " + tT1.ToString() + "\r\n");// отладка hcERR err; // Код ошибки hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcHSTMT pOper; // Адрес памяти, куда будет записан идентификатор оператора. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации int pCol = 0; // количество колонок long pStr = 0; // количество строк hcRECNO unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . char *strConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text);// Сервер char *strLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox4->Text);// Логин char *strPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox5->Text);// Пароль char *strSql = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox6->Text);// поле SQL DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу if(err = hcSqlInit(&Init) != 0 ) textBox2->AppendText("Ошибка ""Инициализация клиентской части"" err= " + err + "\r\n"); // Инициализация клиентской части if(err = hcSqlCheckInit() < 0 ) textBox2->AppendText("Ошибка ""Завершения инициализации"" err= " + err + "\r\n"); // Проверка завершения инициализации if(err = hcSqlAllocConnect(&pdb) != 0 ) textBox2->AppendText("Ошибка ""Создать соединение"" err= " + err + "\r\n");// Создать соединение if(err = hcSqlConnect(pdb, strConnect, strLogin, strPassword) != 0) textBox2->AppendText("Ошибка ""Установить связь с СУБД"" err= " + err + "\r\n"); //Установить связь с СУБД if(err = hcSqlAllocStmt(pdb, &pOper) != 0)textBox2->AppendText("Ошибка ""Создать оператор"" err= " + err + "\r\n"); // Создать оператор if(err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)1, 0) != 0) textBox2->AppendText("Ошибка ""Изменение параметров оператора"" err= " + err + "\r\n"); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях if(err = hcSqlExecDirect(pOper, strSql) != 0) textBox2->AppendText("Ошибка Выполнвыполнения SQL-запроса err= " + err + "\r\n"); // Выполняем SQLзапрос if(err = hcSqlNumResultCols (pOper, &pCol ) != 0) textBox2->AppendText("Ошибка Получить количество колонок результата err= " + err + "\r\n"); // Получить количество колонок результата if(err = hcSqlRowCount (pOper, &pStr ) != 0) textBox2->AppendText("Ошибка Получить количество строк результата err= " + err + "\r\n"); // Получить количество строк результата if(err = hcSqlOpenResults (pOper, &pRecSize ) != 0) textBox2->AppendText("Ошибка Открытие результатов для чтения err= " + err + "\r\n"); // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" if (err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * SIZE_HCSQLDSTINFOT, &cntOp) != 0) textBox2->AppendText("Ошибка Получить информацию об операторе err= " + err + "\r\n");// Получить информацию об операторе for (int i = 0; i < pCol; i++) //заполняем виртуальную таблу колонки названиями dT->Columns->Add(gcnew String(infCol[i].fname, 0, 32, System::Text::Encoding::GetEncoding(866))); char *bufOut = new char[pRecSize * 10]; // Адрес буфера для присылаемых записей. tT3 = DateTime::Now; // отладка засекли время for( long i = 0; i < pStr; i++ ) // проход по всем строкам { unsigned cntOut = 0; // число байтов помещенных в буфер err = hcSqlReadResults(pOper, i, bufOut, pRecSize * 10 , &cntOut);// Чтение результатов char *p = bufOut; // делаем указатель на буфер if (cntOut == 0 || err != 0) break; // если буфер пустой или ошибка ф-ции выскакиваем из цикла int nomRecBuf = cntOut / pRecSize; // число записей записанных в буфер for(long ib=0; ib<nomRecBuf; ib++) // перебираем строки записанные в буфер { DataRow ^dR = dT->NewRow(); // Создаем новую строку в виртуальной таблице for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n" ;// отладка } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины dR[j] = *reinterpret_cast<unsigned char *>(p) ; break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p); } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p); } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; }// в зависимости от типа ложим в ячеку преобразовывая к этому типу p += infCol[j].len ;// сдвигаем указатель на длину поля, чтобы указывал на начало следующего поля } dT->Rows->Add( dR );// Добавляем созданную и заполненую строку в виртуальную таблицу } if( i > 99 ) break ; // выпрыгиваем из цикла (заданное количество строк выбрали) i = i + nomRecBuf ; } tT4 = DateTime::Now; textBox2->AppendText("выбрали 100 строк (без выгрузки в датаГрид) " + (tT4 - tT3).ToString() +"\r\n");// отладка dataGridView2->DataSource = dT; // Выгружаем всю виртуальтую таблу в датаГрид tT5 = DateTime::Now; textBox2->AppendText("Выгрузка в датаГрид) " + (tT5 - tT4).ToString() + "\r\n");// отладка hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы toolStripStatusLabel2->Text = pStr.ToString(); // показываем количество строк toolStripStatusLabel5->Text = pCol.ToString(); // показываем количество полей tT2 = DateTime::Now; textBox2->AppendText("Финишь выполнялось " + (tT2 - tT1).ToString() +"\r\n");// отладка } //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\\ Прикреплённая картинка
|
Сообщ.
#211
,
|
|
|
Цитата kms @ Цитата Cfon @ а эта функция что делает? считывает 140 мил строк подсчитывает и возвращает результат? ну тут я уж не знаю , потому что она в dll-ке , и сама СУБД HyTech где то проскакивало сообщение что она вообще задумывалась как NoSQL и первые версии так и были , (сама СУБД на инвертированных списках)поетому можно только гадать че там, есть желание открой dll-ку и посмотри че там SQl или че то другое я к тому что строка эта получена не через считывание 140 мил строк данных а SQL там не SQL уже не важно Цитата kms @ Цитата Олег М @ совсем запарился , И покажи код на данный момент вот что получается , по нажатию кнопки запрос идет на все таблицу в почти 5млн строк, но выводится в датаГрид только около 100 , точно ни когда не будет , ближайшее число после сотни на котором мы выходим из цикла Скрытый текст private: System::Void toolStripButton5_Click(System::Object^ sender, System::EventArgs^ e) { #define SIZE_HCSQLDSTINFOT 128 DateTime tT1, tT2, tT3, tT4 , tT5; tT1 = DateTime::Now; textBox2->AppendText("Старт " + tT1.ToString() + "\r\n");// отладка hcERR err; // Код ошибки hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcHSTMT pOper; // Адрес памяти, куда будет записан идентификатор оператора. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации int pCol = 0; // количество колонок long pStr = 0; // количество строк hcRECNO unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . char *strConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text);// Сервер char *strLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox4->Text);// Логин char *strPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox5->Text);// Пароль char *strSql = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox6->Text);// поле SQL DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу if(err = hcSqlInit(&Init) != 0 ) textBox2->AppendText("Ошибка ""Инициализация клиентской части"" err= " + err + "\r\n"); // Инициализация клиентской части if(err = hcSqlCheckInit() < 0 ) textBox2->AppendText("Ошибка ""Завершения инициализации"" err= " + err + "\r\n"); // Проверка завершения инициализации if(err = hcSqlAllocConnect(&pdb) != 0 ) textBox2->AppendText("Ошибка ""Создать соединение"" err= " + err + "\r\n");// Создать соединение if(err = hcSqlConnect(pdb, strConnect, strLogin, strPassword) != 0) textBox2->AppendText("Ошибка ""Установить связь с СУБД"" err= " + err + "\r\n"); //Установить связь с СУБД if(err = hcSqlAllocStmt(pdb, &pOper) != 0)textBox2->AppendText("Ошибка ""Создать оператор"" err= " + err + "\r\n"); // Создать оператор if(err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)1, 0) != 0) textBox2->AppendText("Ошибка ""Изменение параметров оператора"" err= " + err + "\r\n"); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях if(err = hcSqlExecDirect(pOper, strSql) != 0) textBox2->AppendText("Ошибка Выполнвыполнения SQL-запроса err= " + err + "\r\n"); // Выполняем SQLзапрос if(err = hcSqlNumResultCols (pOper, &pCol ) != 0) textBox2->AppendText("Ошибка Получить количество колонок результата err= " + err + "\r\n"); // Получить количество колонок результата if(err = hcSqlRowCount (pOper, &pStr ) != 0) textBox2->AppendText("Ошибка Получить количество строк результата err= " + err + "\r\n"); // Получить количество строк результата if(err = hcSqlOpenResults (pOper, &pRecSize ) != 0) textBox2->AppendText("Ошибка Открытие результатов для чтения err= " + err + "\r\n"); // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" if (err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * SIZE_HCSQLDSTINFOT, &cntOp) != 0) textBox2->AppendText("Ошибка Получить информацию об операторе err= " + err + "\r\n");// Получить информацию об операторе for (int i = 0; i < pCol; i++) //заполняем виртуальную таблу колонки названиями dT->Columns->Add(gcnew String(infCol[i].fname, 0, 32, System::Text::Encoding::GetEncoding(866))); char *bufOut = new char[pRecSize * 10]; // Адрес буфера для присылаемых записей. tT3 = DateTime::Now; // отладка засекли время for( long i = 0; i < pStr; i++ ) // проход по всем строкам { unsigned cntOut = 0; // число байтов помещенных в буфер err = hcSqlReadResults(pOper, i, bufOut, pRecSize * 10 , &cntOut);// Чтение результатов char *p = bufOut; // делаем указатель на буфер if (cntOut == 0 || err != 0) break; // если буфер пустой или ошибка ф-ции выскакиваем из цикла int nomRecBuf = cntOut / pRecSize; // число записей записанных в буфер for(long ib=0; ib<nomRecBuf; ib++) // перебираем строки записанные в буфер { DataRow ^dR = dT->NewRow(); // Создаем новую строку в виртуальной таблице for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n" ;// отладка } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины dR[j] = *reinterpret_cast<unsigned char *>(p) ; break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p); } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p); } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; }// в зависимости от типа ложим в ячеку преобразовывая к этому типу p += infCol[j].len ;// сдвигаем указатель на длину поля, чтобы указывал на начало следующего поля } dT->Rows->Add( dR );// Добавляем созданную и заполненую строку в виртуальную таблицу } if( i > 99 ) break ; // выпрыгиваем из цикла (заданное количество строк выбрали) i = i + nomRecBuf ; } tT4 = DateTime::Now; textBox2->AppendText("выбрали 100 строк (без выгрузки в датаГрид) " + (tT4 - tT3).ToString() +"\r\n");// отладка dataGridView2->DataSource = dT; // Выгружаем всю виртуальтую таблу в датаГрид tT5 = DateTime::Now; textBox2->AppendText("Выгрузка в датаГрид) " + (tT5 - tT4).ToString() + "\r\n");// отладка hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы toolStripStatusLabel2->Text = pStr.ToString(); // показываем количество строк toolStripStatusLabel5->Text = pCol.ToString(); // показываем количество полей tT2 = DateTime::Now; textBox2->AppendText("Финишь выполнялось " + (tT2 - tT1).ToString() +"\r\n");// отладка } //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\\ это потому что тебе надо сделать рефакторинг кода иначе кердык как я уже говорил надо разбить код на небольшие функции ~по 20-50 строк кода, потом если приспичет то и на классы |
Сообщ.
#212
,
|
|
|
Цитата Cfon @ это потому что тебе надо сделать рефакторинг кода иначе кердык как я уже говорил надо разбить код на небольшие функции ~по 20-50 строк кода, потом если приспичет то и на классы ребята вот полностью с вами согласен, но рано еще очень рано , класы это хорошо все когда сам алгоритм понятен и работает как квантовые часы вселенной , но пока иден отладка не хотелось все это путать в классы Добавлено Цитата Cfon @ сделать рефакторинг кода иначе кердык это как ??? в смысле в MSVS2015C++Express , а как ???? |
Сообщ.
#213
,
|
|
|
Цитата kms @ for( long i = 0; i < pStr; i++ ) // проход по всем строкам Ты пытаешься вычитать по 10 строк. Здесь тебе надо делать for( long i = 0; ; i += 10) Условие не нужно вообще, т.к. у тебя ниже есть break Добавлено Цитата kms @ err = hcSqlReadResults(pOper, i, bufOut, pRecSize * 10 , &cntOut);// Чтение результатов Замени везде цифру 10 на константу static const size_t _n = 50; err = hcSqlReadResults(pOper, i, bufOut, pRecSize * _n , &cntOut) // Чтение результатов ..... for( long i = 0; ; i += _n) // проход по всем строкам ...... err = hcSqlReadResults(pOper, i, bufOut, pRecSize * _n , &cntOut); Покажи чему равны err, pRecSize и cntOut, после первой итерации, hcSqlReadResults |
Сообщ.
#214
,
|
|
|
Цитата Олег М @ Ты пытаешься вычитать по 10 строк. Здесь тебе надо делать for( long i = 0; ; i += 10) Условие не нужно вообще, т.к. у тебя ниже есть break а ну точно , да Добавлено Цитата Олег М @ Замени везде цифру 10 на константу ОК делаю |
Сообщ.
#215
,
|
|
|
Сообщ.
#216
,
|
|
|
Всё правильно. Сделай по 50
|
Сообщ.
#217
,
|
|
|
Цитата Олег М @ Сделай по 50 в смысле в место 10 поставить 50 |
Сообщ.
#218
,
|
|
|
Сообщ.
#219
,
|
|
|
Сообщ.
#220
,
|
|
|
Что-то ты неправильно делаешь, в cntOut должно быть 2034 * 50 = 101700.
Покажи код Добавлено Цитата kms @ вот на такой табличке получилось , у нее полей мало Здесь вроде нормально |
Сообщ.
#221
,
|
|
|
я же не вывожу на экран 2034 * 50
Добавлено а все три переменные отдельно |
Сообщ.
#222
,
|
|
|
Цитата kms @ хмы хм хм очень интересно , на другой таблице с 94 полями тоже прошло хотя раньше не проходило Так может раньше в ней было 19 строчек, поэтому оно тебе и выбирало 19 строчек, даже когда ты указывал по 50 ? Ты явно что то не так делаешь, либо API этой базы кривое. Одно из двух. Посмотри все коды ошибок от всех вызовов фунций до hcSqlReadResults и от нее тоже, приведи сюда свой код, именно такой - какой не работает, а не какой нибудь исправленный, посмотри какого размера буфер ты передаешь, посмотри сколько оно реально считывает, проверь код ошибки. Если вычитывает 10 записей нормально, то должно и 50 и 100 вычитывать нормально. И убедись на 100% чтобы в таблице, из которой ты читаешь было дофига данных, не 10 строчек, а хотя бы ну тысяча, или больше. |
Сообщ.
#223
,
|
|
|
Цитата kms @ я же не вывожу на экран 2034 * 50 Это тебе hcSqlReadResults должна такую цифру возвращать - 50 записей, каждая размером 2034. А там возвращается только 17 записей |
Сообщ.
#224
,
|
|
|
вычитка строк вынес в отдельную ф-цию
/// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| void PasStr(int pOper , hcSqlDstInfoT *infCol, unsigned pRecSize , int pCol, long pStr ) { static const size_t _n10 = 50; int err = 0; DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу for (int k = 0; k < pCol; k++) //заполняем виртуальную таблу колонки названиями dT->Columns->Add(gcnew String(infCol[k].fname, 0, 32, System::Text::Encoding::GetEncoding(866))); char *bufOut = new char[pRecSize * _n10]; // Адрес буфера для присылаемых записей. for (long i = 0; ; i+= _n10) // проход по всем строкам { unsigned cntOut = 0; // число байтов помещенных в буфер err = hcSqlReadResults(pOper, i, bufOut, pRecSize * _n10, &cntOut);// Чтение результатов textBox2->AppendText("№прохода=" + i +" err= " + err+ " pRecSize= " + pRecSize +" cntOut= " + cntOut +"\r\n");// отладка char *p = bufOut; // делаем указатель на буфер if (cntOut == 0 || err != 0) break; // если буфер пустой или ошибка ф-ции выскакиваем из цикла int nomRecBuf = cntOut / pRecSize; // число записей записанных в буфер for (long ib = 1; ib <= nomRecBuf; ib++) // перебираем строки записанные в буфер { DataRow ^dR = dT->NewRow(); // Создаем новую строку в виртуальной таблице for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n";// отладка } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины dR[j] = *reinterpret_cast<unsigned char *>(p); break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p); } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p); } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len;// сдвигаем указатель на длину поля, чтобы указывал на начало следующего поля } dT->Rows->Add(dR);// Добавляем созданную и заполненую строку в виртуальную таблицу } if (i > 89) break; // выпрыгиваем из цикла (заданное количество строк выбрали) } dataGridView2->DataSource = dT; // Выгружаем всю виртуальтую таблу в датаГрид } //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| |
Сообщ.
#225
,
|
|
|
Цитата kms @ вычитка строк вынес в отдельную ф-цию Попробуй пока эту функцию закоментировать, и переделать ее вот на такую: void PasStr(int pOper , hcSqlDstInfoT *infCol, unsigned pRecSize , int pCol, long pStr ) { static const size_t _n10 = 50; long position = 0; int err = 0; char *bufOut = new char[pRecSize * _n10]; // Адрес буфера для присылаемых записей. unsigned cntOut = 0; // число байтов помещенных в буфер err = hcSqlReadResults(pOper, position, bufOut, pRecSize * _n10, &cntOut);// Чтение результатов textBox2->AppendText(" err= " + err+ " pRecSize*_n10= " + (pRecSize*_n10) +" cntOut= " + cntOut +"\r\n");// отладка } Всю остальную портянку закоментируй вообще, потому что она мешает и тебе и нам. Вот добейся чтоб эти четыре строчки вычитали тебе 50 записей из таблицы. Добавлено Цитата KILLER @ Вот добейся чтоб эти четыре строчки вычитали тебе 50 записей из таблицы. Вернее чтоб у тебя в cntOut было число pRecSize * _n10 или очень близкое к этому после вызова hcSqlReadResults. Добавлено И обязательно проверь что таблица, из которой ты читаешь данные содержала много строчек. А то может ты вычитываешь из таблице в которой 19 записей, а мы тут копья ломаем. Добавлено И к слову, вот ты там выкладывал HyTech папку с базой, говоришь там надо запустить sql64.exe и из меню Система запустить сервер. Я запускаю эту консоль, у меня открывается окно, все пучком, но как потом зайти в меню система? Ни на мышку, ни на клаву эта консоль вообще не реагирует. Правда я запускаю под Win 10. на всякие Alt+x, Alt+P не реагирует. Добавлено Видимо из за этого трабла у меня и не коннектилось к базе. |
Сообщ.
#226
,
|
|
|
А pRecSize там точно 2034 должен быть, для 94 полей?
|
Сообщ.
#227
,
|
|
|
Кароче, в общем я нашел способ запустить твою программу на виртуалке, выкладывай проект с MSVS.
Добавлено Слушай kms . Вот ты реально прикалываешься с нас? Все оно работает. Вот я сейчас проверил даже на старом коде считывает 50 записей за 1 раз. Как у тебя не считывает, расскажи пожалуйста? И выводит и считывает без всяких циклов 50 записей. Я не знаю как у тебя там в твоем новом коде, но вот в старом у тебя там куча левых, непонятных циклов, которые вообще в принципе не нужны. Добавлено Честно выводит 100 записей, можно изменить константу _n10 на другое значение и она будет именно столько и вычитывать. И твой код я практически не трогал, просто вынес чтение за цикл и убрал лишние портянки кода. private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { hcERR err; // Код ошибки hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcHSTMT pOper; // Адрес памяти, куда будет записан идентификатор оператора. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации int pCol = 0; // количество колонок hcRECNO pStr = 0; // количество строк unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . char *strConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text);// Сервер char *strLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox4->Text);// Логин char *strPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox5->Text);// Пароль char *strSql = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox6->Text);// поле SQL int one = 1; if (err = hcSqlInit(&Init) != 0) textBox2->AppendText("Ошибка с параметрами инициализации \n"); // Инициализация клиентской части if (hcSqlCheckInit() < 0) textBox2->AppendText("Ошибка завершения инициализации \n"); // Проверка завершения инициализации err = hcSqlAllocConnect(&pdb); //----------------------------- Создать соединение err = hcSqlConnect(pdb, strConnect, strLogin, strPassword); //Установить связь с СУБД err = hcSqlAllocStmt(pdb, &pOper); // Создать оператор 2раз err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)one, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях err = hcSqlExecDirect(pOper, strSql); // Выполняем SQLзапрос err = hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата err = hcSqlRowCount(pOper, &pStr); // Получить количество строк результата err = hcSqlOpenResults(pOper, &pRecSize); // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" textBox2->AppendText("Кол-во столбиков pCol = " + pCol + "\r\n"); // отладка // err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе static const size_t _n10 = 100; DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу for (int k = 0; k < pCol; k++) //заполняем виртуальную таблу колонки названиями dT->Columns->Add(gcnew String(infCol[k].fname, 0, 32, System::Text::Encoding::GetEncoding(866))); int initpos = 0; char *bufOut = new char[pRecSize * _n10]; // Адрес буфера для присылаемых записей. unsigned cntOut = 0; // число байтов помещенных в буфер err = hcSqlReadResults(pOper, initpos, bufOut, pRecSize * _n10, &cntOut);// Чтение результатов textBox2->AppendText("№Считали записей =" + cntOut / pRecSize + " err= " + err + " pRecSize= " + pRecSize + " cntOut= " + cntOut + "\r\n");// отладка char *p = bufOut; // делаем указатель на буфер int nomRecBuf = cntOut / pRecSize; // число записей записанных в буфер for (long ib = 0; ib < nomRecBuf; ib++) // перебираем строки записанные в буфер { DataRow ^dR = dT->NewRow(); // Создаем новую строку в виртуальной таблице for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n";// отладка } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины dR[j] = *reinterpret_cast<unsigned char *>(p); break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p); } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p); } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len;// сдвигаем указатель на длину поля, чтобы указывал на начало следующего поля } dT->Rows->Add(dR);// Добавляем созданную и заполненую строку в виртуальную таблицу } dataGridView2->DataSource = dT; // Выгружаем всю виртуальтую таблу в датаГрид hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы } |
Сообщ.
#228
,
|
|
|
Сообщ.
#229
,
|
|
|
И к слову, если в hcSqlReadResults(pOper, initpos, bufOut, pRecSize * _n10, &cntOut); - initpos изменить с 0 на любое другое число, то будет читать с той позиции, которую задал, и если вдруг там записей останется меньше, чем размер буфера, все корректно будет вычитываться. Вот например я задал вычитать 250 записей, мне вычитало 130, потому что больше в твоей таблице нет записей.
В общем бери теперь вот этот код и делай декомпозицию. Разноси все это по классам. Причесывай, избавляйся от magic numbers, лишних циклов и т.д. |
Сообщ.
#230
,
|
|
|
Цитата KILLER @ Кароче, в общем я нашел способ запустить твою программу на виртуалке, выкладывай проект с MSVS. вот проект https://yadi.sk/d/-7GjI7Ku3GDpW2 вот СУБД уже с БД https://yadi.sk/d/Aw5CyDg33FrdpD Добавлено саму СУБД папку HyTech из архива ложи на диск C:\ или на другой любой (только тогда в sql64.ini замени все буквы С:\ на свою куда положил) запускай sql64.exe , и все у тебя СУБД HyTech работает , а уже после этого запускается проект из которого ты подключаешься |
Сообщ.
#231
,
|
|
|
Цитата KILLER @ Вернее чтоб у тебя в cntOut было число pRecSize * _n10 или очень близкое к этому после вызова hcSqlReadResults. вот переделал как ты сказал , ОК в буфер залетает кол-во байтов равное установленному т.е. (pRecSize * _n50) = cntOut void PasStr(int pOper, hcSqlDstInfoT *infCol, unsigned pRecSize, int pCol, long pStr) { static const size_t _n50 = 50; long position = 0; int err = 0; char *bufOut = new char[pRecSize * _n50]; // Адрес буфера для присылаемых записей. unsigned cntOut = 0; // число байтов помещенных в буфер err = hcSqlReadResults(pOper, position, bufOut, pRecSize * _n50, &cntOut);// Чтение результатов textBox2->AppendText(" err = " + err + "\r\n");// отладка textBox2->AppendText("размер одной строки pRecSize = " + pRecSize + " \r\n");// отладка textBox2->AppendText("сколько байтов вычитала ф-ция cntOut = " + cntOut + "\r\n");// отладка textBox2->AppendText("какой размер буфера установили ( pRecSize * _n50 ) = " + (pRecSize * _n50) + "\r\n");// отладка } Добавлено Цитата Олег М @ Что-то ты неправильно делаешь, в cntOut должно быть 2034 * 50 = 101700. Покажи код Добавлено Сегодня, 11:36 Цитата kms @ Сегодня, 11:23 вот на такой табличке получилось , у нее полей мало Здесь вроде нормально Цитата KILLER @ Слушай kms . Вот ты реально прикалываешься с нас? Все оно работает. Вот я сейчас проверил даже на старом коде считывает 50 записей за 1 раз. Как у тебя не считывает, расскажи пожалуйста? Я не знаю почему оно так получается , я же говорю ф-ция сколько захотела столько и прочитала я не пойму почему так Добавлено Цитата KILLER @ Так может раньше в ней было 19 строчек, поэтому оно тебе и выбирало 19 строчек, даже когда ты указывал по 50 ? да точно до меня только дошло , по моему я табличку выбирал малюсенькую , извиняюсь за невнимательность |
Сообщ.
#232
,
|
|
|
Цитата KILLER @ Ты явно что то не так делаешь, либо API этой базы кривое. Одно из двух. Посмотри все коды ошибок от всех вызовов фунций до hcSqlReadResults и от нее тоже, приведи сюда свой код, именно такой - какой не работает, а не какой нибудь исправленный, посмотри какого размера буфер ты передаешь, посмотри сколько оно реально считывает, проверь код ошибки. Если вычитывает 10 записей нормально, то должно и 50 и 100 вычитывать нормально. И убедись на 100% чтобы в таблице, из которой ты читаешь было дофига данных, не 10 строчек, а хотя бы ну тысяча, или больше. сейчас вот такая ф-ция Скрытый текст /// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| void PasStr(int pOper , hcSqlDstInfoT *infCol, unsigned pRecSize , int pCol, long pStr ) { static const size_t _n50 = 50; int err = 0; DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу for (int k = 0; k < pCol; k++) //заполняем виртуальную таблу колонки названиями dT->Columns->Add(gcnew String(infCol[k].fname, 0, 32, System::Text::Encoding::GetEncoding(866))); char *bufOut = new char[pRecSize * _n50]; // Адрес буфера для присылаемых записей. for (long i = 0; ; i+= _n50) // проход по всем строкам { unsigned cntOut = 0; // число байтов помещенных в буфер err = hcSqlReadResults(pOper, i, bufOut, pRecSize * _n50, &cntOut);// Чтение результатов textBox2->AppendText("№прохода=" + i +" err= " + err+ " pRecSize= " + pRecSize +" cntOut= " + cntOut +"\r\n");// отладка char *p = bufOut; // делаем указатель на буфер if (cntOut == 0 || err != 0) break; // если буфер пустой или ошибка ф-ции выскакиваем из цикла int nomRecBuf = cntOut / pRecSize; // число записей записанных в буфер for (long ib = 1; ib <= nomRecBuf; ib++) // перебираем строки записанные в буфер { DataRow ^dR = dT->NewRow(); // Создаем новую строку в виртуальной таблице for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n";// отладка } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины dR[j] = *reinterpret_cast<unsigned char *>(p); break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p); } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p); } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len;// сдвигаем указатель на длину поля, чтобы указывал на начало следующего поля } dT->Rows->Add(dR);// Добавляем созданную и заполненую строку в виртуальную таблицу } if (i > 89) break; // выпрыгиваем из цикла (заданное количество строк выбрали) } dataGridView2->DataSource = dT; // Выгружаем всю виртуальтую таблу в датаГрид } //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| возвращает вот такую картину, в таблице как видно почти 5млн. строк и 10полей, выборка по 50 строк Прикреплённая картинка
Добавлено вот этот проект https://yadi.sk/d/RfniM8oU3GDz93 Добавлено Цитата KILLER @ И обязательно проверь что таблица, из которой ты читаешь данные содержала много строчек. А то может ты вычитываешь из таблице в которой 19 записей, а мы тут копья ломаем. все исправил , и учел но я реально не знаю как обойтись без цикло чтобы вывести в ДатаГрид по ячейкам Добавлено Цитата KILLER @ И к слову, вот ты там выкладывал HyTech папку с базой, говоришь там надо запустить sql64.exe и из меню Система запустить сервер. Я запускаю эту консоль, у меня открывается окно, все пучком, но как потом зайти в меню система? Ни на мышку, ни на клаву эта консоль вообще не реагирует. Правда я запускаю под Win 10. на всякие Alt+x, Alt+P не реагирует. да к сожалению оно не работает на Win10, максимум я вот спокойно работаю на Win7x64 и Win7x32 Добавлено Цитата Олег М @ А pRecSize там точно 2034 должен быть, для 94 полей? ну да pRecSize всегда равен сумме размерностей полей Добавлено Цитата KILLER @ Слушай kms . Вот ты реально прикалываешься с нас? ну вот мне делать больше нечего, не не ребята ни в коем случае |
Сообщ.
#233
,
|
|
|
Цитата KILLER @ В общем бери теперь вот этот код и делай декомпозицию. Разноси все это по классам. Причесывай, избавляйся от magic numbers, лишних циклов и т.д. ОК , понял , делаю dll , в dll можно же классом, но тогда я не смогу использовать эту dll-ку из C# я правильно понял ??? |
Сообщ.
#234
,
|
|
|
Цитата kms @ char *bufOut = new char[pRecSize * _n50]; // Адрес буфера для присылаемых записей. Не забудь при выходе из функции сделать delete[] bufOut; А ещё лучше объяви этот буфер так std::unique_ptr<char[]> bufOut(new char[pRecSize * _n50]); и всё |
Сообщ.
#235
,
|
|
|
Цитата Олег М @ Не забудь при выходе из функции сделать delete[] bufOut; понял я так и хотел сделать , Цитата Олег М @ А ещё лучше объяви этот буфер так std::unique_ptr<char[]> bufOut(new char[pRecSize * _n50]); ага а вот этого не знал щас попробую |
Сообщ.
#236
,
|
|
|
Цитата kms @ все исправил , и учел но я реально не знаю как обойтись без цикло чтобы вывести в ДатаГрид по ячейкам Я же тебе скинул уже готовый пример с выводом в таблицу. Вот он: private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { hcERR err; // Код ошибки hcHDB pdb; // Адрес памяти, куда будет записан идентификатор соединения. hcHSTMT pOper; // Адрес памяти, куда будет записан идентификатор оператора. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации int pCol = 0; // количество колонок hcRECNO pStr = 0; // количество строк unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . char *strConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text);// Сервер char *strLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox4->Text);// Логин char *strPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox5->Text);// Пароль char *strSql = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox6->Text);// поле SQL int one = 1; if (err = hcSqlInit(&Init) != 0) textBox2->AppendText("Ошибка с параметрами инициализации \n"); // Инициализация клиентской части if (hcSqlCheckInit() < 0) textBox2->AppendText("Ошибка завершения инициализации \n"); // Проверка завершения инициализации err = hcSqlAllocConnect(&pdb); //----------------------------- Создать соединение err = hcSqlConnect(pdb, strConnect, strLogin, strPassword); //Установить связь с СУБД err = hcSqlAllocStmt(pdb, &pOper); // Создать оператор 2раз err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)one, 0); // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях err = hcSqlExecDirect(pOper, strSql); // Выполняем SQLзапрос err = hcSqlNumResultCols(pOper, &pCol); // Получить количество колонок результата err = hcSqlRowCount(pOper, &pStr); // Получить количество строк результата err = hcSqlOpenResults(pOper, &pRecSize); // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" textBox2->AppendText("Кол-во столбиков pCol = " + pCol + "\r\n"); // отладка // err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * sizeof(hcSqlDstInfoT), &cntOp);// Получить информацию об операторе static const size_t _n10 = 100; DataTable ^dT = gcnew DataTable(); // делаем виртуальную таблицу for (int k = 0; k < pCol; k++) //заполняем виртуальную таблу колонки названиями dT->Columns->Add(gcnew String(infCol[k].fname, 0, 32, System::Text::Encoding::GetEncoding(866))); int initpos = 0; char *bufOut = new char[pRecSize * _n10]; // Адрес буфера для присылаемых записей. unsigned cntOut = 0; // число байтов помещенных в буфер err = hcSqlReadResults(pOper, initpos, bufOut, pRecSize * _n10, &cntOut);// Чтение результатов textBox2->AppendText("№Считали записей =" + cntOut / pRecSize + " err= " + err + " pRecSize= " + pRecSize + " cntOut= " + cntOut + "\r\n");// отладка char *p = bufOut; // делаем указатель на буфер int nomRecBuf = cntOut / pRecSize; // число записей записанных в буфер for (long ib = 0; ib < nomRecBuf; ib++) // перебираем строки записанные в буфер { DataRow ^dR = dT->NewRow(); // Создаем новую строку в виртуальной таблице for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной dR[j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866)) + "\r\n";// отладка } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины dR[j] = *reinterpret_cast<unsigned char *>(p); break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dR[j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dR[j] = *reinterpret_cast<signed short *>(p); } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dR[j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dR[j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dR[j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dR[j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dR[j] = *reinterpret_cast<float *>(p); } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dR[j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dR[j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dR[j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len;// сдвигаем указатель на длину поля, чтобы указывал на начало следующего поля } dT->Rows->Add(dR);// Добавляем созданную и заполненую строку в виртуальную таблицу } dataGridView2->DataSource = dT; // Выгружаем всю виртуальтую таблу в датаГрид hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы Тут hcSqlReadResults вызывается в не цикла, как и должно быть. Вот по сути это рабочий пример, который уже можно разносить по классам. Цитата kms @ ОК , понял , делаю dll , в dll можно же классом, но тогда я не смогу использовать эту dll-ку из C# Сначало создай класс, и засунь работу с БД в этот класс. По поводу использования dllки в C#, ну люди же как то используют. Значит можно будет использовать в C#. Пока просто класс отдельный сделай для работы с БД, без всяких DataTable. |
Сообщ.
#237
,
|
|
|
ругается namespace std не содержит члена unique_ptr
|
Сообщ.
#238
,
|
|
|
Сделай #include <memory>
|
Сообщ.
#239
,
|
|
|
Цитата KILLER @ Тут hcSqlReadResults вызывается в не цикла, как и должно быть. Вот по сути это рабочий пример, который уже можно разносить по классам. ОК , я уже это с твоего примера так и сделал Добавлено Цитата Олег М @ Senior Member Профиль · PM Рейтинг (т): [ 41 ] Сделай #include <memory> ОК так подключил теперь другая ошибка |
Сообщ.
#240
,
|
|
|
В hcSqlReadResults? Сделай там bufOut.get(). И char * p = bufOut.get();
|
Сообщ.
#241
,
|
|
|
Цитата Олег М @ А ещё лучше объяви этот буфер так std::unique_ptr<char[]> bufOut(new char[pRecSize * _n50]); Не факт что у него такой код заведется. Он там на С++/CLI пишет, вот я как то не уверен что этот С++/CLI поддерживает новый стандарт, хотя могу и ошибаться, возможно в 15 студии они и сделали в этом C++/CLI поддержку хотя бы С++11 |
Сообщ.
#242
,
|
|
|
СерьезностьКодОписаниеПроектФайлСтрокаСостояние подавления ОшибкаC2440инициализация: невозможно преобразовать "std::unique_ptr<char [],std::default_delete<_Ty>>" в "char *"ComHyTech \desktop\comhytech\comhytech\comhytech.cpp79 Добавлено Цитата Олег М @ В hcSqlReadResults? Сделай там bufOut.get(). И char * p = bufOut.get(); ОК , ошибка ушла Добавлено Цитата KILLER @ Не факт что у него такой код заведется. Он там на С++/CLI пишет, вот я как то не уверен что этот С++/CLI поддерживает новый стандарт, хотя могу и ошибаться, возможно в 15 студии они и сделали в этом C++/CLI поддержку хотя бы С++11 я DLL-ку клепаю щас код выложу , уже сделал Добавлено // ComHyTech.cpp: определяет экспортированные функции для приложения DLL. // #include "stdafx.h" #define HYCFG_WIN32 #include "HSCLI.H" //#include <cstring> #include <stdio.h> #include <string> #include <iostream> #include <memory> #define SIZE_HCSQLDSTINFOT 128 using namespace std; int err = 0; // Код ошибки int pdb = 0; // Адрес памяти, куда будет записан идентификатор соединения. int pOper = 0; // Адрес памяти, куда будет записан идентификатор оператора. int pCol = 0; // количество колонок long pStr = 0; // количество строк hcRECNO unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . string ConnectServer(char *pStrConnect, char *pStrLogin, char *pStrPassword) { pStrConnect = "tcpip:/localhost:13000"; // (char*)(void*)Marshal::StringToHGlobalAnsi("");// Сервер pStrLogin = "HTADMIN"; //(char*)(void*)Marshal::StringToHGlobalAnsi("");// Логин pStrPassword = "PASSWORD"; //(char*)(void*)Marshal::StringToHGlobalAnsi("");// Пароль hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации if (err = hcSqlInit(&Init) != 0) return "Ошибка Инициализация клиентской части err= " + err; // Инициализация клиентской части if (err = hcSqlCheckInit() < 0) return "Ошибка ""Завершения инициализации"" err= " + err; // Проверка завершения инициализации if (err = hcSqlAllocConnect(&pdb) != 0) return "Ошибка ""Создать соединение"" err= " + err; // Создать соединение if (err = hcSqlConnect(pdb, pStrConnect, pStrLogin, pStrPassword) != 0) return "Ошибка ""Установить связь с СУБД"" err= " + err; //Установить связь с СУБД return "Функция ConnectServer завершила работу"; } string SqlQuery(char *pStrSql) { pStrSql = ""; //(char*)(void*)Marshal::StringToHGlobalAnsi("");// поле SQL if (err = hcSqlAllocStmt(pdb, &pOper) != 0) return "Ошибка ""Создать оператор"" err= " + err; // Создать оператор if (err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)1, 0) != 0) return "Ошибка ""Изменение параметров оператора"" err= " + err; // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях if (err = hcSqlExecDirect(pOper, pStrSql) != 0) return "Ошибка Выполнвыполнения SQL-запроса err= " + err; // Выполняем SQLзапрос if (err = hcSqlNumResultCols(pOper, &pCol) != 0) return "Ошибка Получить количество колонок результата err= " + err; // Получить количество колонок результата if (err = hcSqlRowCount(pOper, &pStr) != 0) return "Ошибка Получить количество строк результата err= " + err; // Получить количество строк результата if (err = hcSqlOpenResults(pOper, &pRecSize) != 0) return "Ошибка Открытие результатов для чтения err= " + err; // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" if (err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * SIZE_HCSQLDSTINFOT, &cntOp) != 0) return "Ошибка Получить информацию об операторе err= " + err;// Получить информацию об операторе return "Функция SqlQuery завершила работу"; } string PasStr(int pOper, hcSqlDstInfoT *infCol, long position, unsigned pRecSize, int pCol, long pStr, string** dataRes) { static const size_t _n50 = 50; dataRes = new string*[_n50]; for (int i = 0; i < pCol; ++i) dataRes[i] = new string[_n50]; //char *bufOut = new char[pRecSize * _n50]; // Адрес буфера для присылаемых записей. unique_ptr<char[]> bufOut(new char[pRecSize * _n50]); unsigned cntOut = 0; // число байтов помещенных в буфер err = hcSqlReadResults(pOper, position, bufOut.get(), pRecSize * _n50, &cntOut);// Чтение результатов char *p = bufOut.get(); // делаем указатель на буфер int nomRecBuf = cntOut / pRecSize; // число записей записанных в буфер for (long ib = 1; ib <= nomRecBuf; ib++) // перебираем строки записанные в буфер { for (int j = 0; j < pCol; j++) // идем по колонкам { switch (infCol[j].type)// в зависимости от типа { case HSCLI_ET_CHAR: { // 0 Массив символов длиной не более заданной //dataRes[ib][j] = gcnew String(p, 0, infCol[j].len, System::Text::Encoding::GetEncoding(866) ) ;// отладка } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины dataRes[ib][j] = *reinterpret_cast<unsigned char *>(p); break; case HSCLI_ET_BYTE: { // 2 Элемент - unsigned char (короткое целое) short //textBox1->AppendText(" " + *reinterpret_cast<unsigned char *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned char *>(p); } break; case HSCLI_ET_INTR: {// 3 Элемент - signed short //textBox1->AppendText(" " + *reinterpret_cast<signed short *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<signed short *>(p); } break; case HSCLI_ET_WORD: { // 4 Элемент - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_DATE: { // 5 Дата - unsigned short //textBox1->AppendText(" " + *reinterpret_cast<unsigned short *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned short *>(p); } break; case HSCLI_ET_NMBR: {//6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); //dataRes[ib][j] = ; } break; case HSCLI_ET_LONG: { //7 Элемент - long int //textBox1->AppendText(" " + *reinterpret_cast<long int *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<long int *>(p); } break; case HSCLI_ET_DWRD: { // 8 Элемент - unsigned long int в БД это dword //textBox1->AppendText(" " + *reinterpret_cast<unsigned long int *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned long int *>(p); } break; case HSCLI_ET_FLOA: { // 9 Элемент - float //textBox1->AppendText(" " + *reinterpret_cast<float *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<float *>(p); } break; case HSCLI_ET_CURR: { // 10 Деньги (double) //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_DFLT: { // 11 Элемент - double //textBox1->AppendText(" " + *reinterpret_cast<double *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<double *>(p); } break; case HSCLI_ET_QINT: { // 12 Элемент - signed __int64 //textBox1->AppendText(" " + *reinterpret_cast<signed __int64 *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<signed __int64 *>(p); } break; case HSCLI_ET_QWRD: { // 13 Элемент - unsigned __int64 //textBox1->AppendText(" " + *reinterpret_cast<unsigned __int64 *>(p) + " "); dataRes[ib][j] = *reinterpret_cast<unsigned __int64 *>(p); } break; } p += infCol[j].len;// сдвигаем указатель на длину поля, чтобы указывал на начало следующего поля } } return ""; // Выгружаем for (int i = 0; i < pCol; ++i) delete[] dataRes[i]; delete[] dataRes; } string CloseSqlQuery(int pOper) { hcSqlCloseResults(pOper); // Закрытие доступа к результатам return "Доступ закрыт"; } string CloseConnectServer(int pdb) { hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы return "Соединение освободили работу завершили"; } Добавлено файл ComHyTech.h #pragma once #define HYCFG_WIN32 #include "HSCLI.H" #include <string> using namespace std; __declspec(dllexport) string ConnectServer(char *pStrConnect, char *pStrLogin, char *pStrPassword); __declspec(dllexport) string SqlQuery(char *pStrSql); __declspec(dllexport) string PasStr(int pOper, hcSqlDstInfoT *infCol, long position, unsigned pRecSize, int pCol, long pStr, string** dataRes); __declspec(dllexport) string CloseSqlQuery(int pOper); __declspec(dllexport) string CloseConnectServer(int pdb); Добавлено сейчас тестирую подключение через , эту dll-ку |
Сообщ.
#243
,
|
|
|
Цитата kms @ return ""; // Выгружаем for (int i = 0; i < pCol; ++i) delete[] dataRes[i]; delete[] dataRes; } Ну и ты реально думаешь что у тебя вызоветься последний for ? Да и вообще я бы в виде класса все делал. Цитата kms @ #pragma once #define HYCFG_WIN32 #include "HSCLI.H" #include <string> using namespace std; __declspec(dllexport) string ConnectServer(char *pStrConnect, char *pStrLogin, char *pStrPassword); __declspec(dllexport) string SqlQuery(char *pStrSql); __declspec(dllexport) string PasStr(int pOper, hcSqlDstInfoT *infCol, long position, unsigned pRecSize, int pCol, long pStr, string** dataRes); Тут в макросы нужно обернуть __declspec(dllexport), иначе как ты будешь импортировать потом это все? |
Сообщ.
#244
,
|
|
|
Цитата KILLER @ Ну и ты реально думаешь что у тебя вызоветься последний for ? нет конечно , это моя не аккуратность, сюда закопипастил так а в проге уже заметил справил Цитата KILLER @ Да и вообще я бы в виде класса все делал. да наверно надо делать как ты говоришь Цитата KILLER @ Тут в макросы нужно обернуть __declspec(dllexport), иначе как ты будешь импортировать потом это все? вообщем оно у меня вообще не работает , хотя компилится без ошибок делаю и DLL-ку и LIB-у , потом собираю тестовый проект подключаю все это хозяйство и не фига , куча ошибок |
Сообщ.
#245
,
|
|
|
Цитата kms @ вообщем оно у меня вообще не работает , хотя компилится без ошибок делаю и DLL-ку и LIB-у , потом собираю тестовый проект подключаю все это хозяйство и не фига , куча ошибок Все верно, это ожидаемо. Потому что ты экспортируешь свои функции, но не импортируешь. Надо писать что то типа того: #pragma once #define HYCFG_WIN32 #include "HSCLI.H" #include <string> #ifdef MY_DLLAPI_EXPORT #define MY_DLLAPI __declspec(dllexport) #else #define MY_DLLAPI __declspec(dllimport) #endif using namespace std; extern "C" { MY_DLLAPI string ConnectServer(char *pStrConnect, char *pStrLogin, char *pStrPassword); MY_DLLAPI string SqlQuery(char *pStrSql); MY_DLLAPI string PasStr(int pOper, hcSqlDstInfoT *infCol, long position, unsigned pRecSize, int pCol, long pStr, string** dataRes); } И в проекте, где у тебя компилируется сама DLL, в опциях проекта в Preprocessor definition прописать MY_DLLAPI_EXPORT В том проекте где используешь свою DLL ничего не нужно делать. Добавлено MY_DLLAPI_EXPORT и MY_DLLAPI можешь по своему обозвать, это я так, для примера их обозвал. Добавлено И еще обернуть эти функции в extern "C" не забудь. Я там в коде что тебе привел, ща поправлю. Добавлено И еще - возвращать std::string из функций в DLL чревато косяками. Нужно бы возвращать const char*, потому что в противном случае по идее может быть бинарная несовместимость с новыми/старыми версиями stl. Но я не уверен на 100% что тут я прав. |
Сообщ.
#246
,
|
|
|
KILLER подскажи пожалуста , как сделать так чтобы уйти от обращения к предыдущим dll-кам а работать только с одной
|
Сообщ.
#247
,
|
|
|
Цитата kms @ KILLER подскажи пожалуста , как сделать так чтобы уйти от обращения к предыдущим dll-кам а работать только с одной В каком смысле? Добавлено Я вопроса не понял просто От обращения к каким dll ты хочешь уйти? Добавлено Если ты про dll от базы данных HyTech, то лучше никак. Они полюбому должны быть с твоим проектом, потому как ты используешь их функционал. Добавлено Тебе по хорошему нужно правильно обернуть работу с БД в свой класс, по крайней мере так будет правильно. Но в принципе можно и функциями обойтись. Это будет работать, но с точки зрения проектирования - это будет не верным подходом. Т.е. это будет не совсем по феншую. А dll, которые ты используешь от БД - если просто - ты от них никак не уйдешь, и это правильно будет, не парься. |
Сообщ.
#248
,
|
|
|
Например:
сначала собираю ComHyTech.dll она использует ф-ции из hscli.dll, сама hscli.dll очень старая написана на Си , поэтому приходится использовать #define HYCFG_WIN32, так вот как так сделать чтобы уже ComHyTech.dll делать на чистом С++ , и так как из ComHyTech.dll идет подключение к hscli.dll приходится в конечном приложении указывать и hscli.h и ComHyTech.h и опять все это #define HYCFG_WIN32 а как все это сделать красиво чисто на С++ Добавлено KILLER океюшки , я все внимательно прочитал, сейчас к вечеру все это переработаю, буду делать так : 1) делаю класс 2) если класс работает , делаю dll-ку с учетом твоих поправок |
Сообщ.
#249
,
|
|
|
файл ComHyTech.h
#pragma once #define HYCFG_WIN32 #include "HSCLI.H" #include <cstring> #include <stdio.h> #include <string> #include <iostream> #include <memory> using namespace std; #define SIZE_HCSQLDSTINFOT 128 ref class ComHyTech { public: ComHyTech(); int ConnectServer(char *pStrConnect, char *pStrLogin, char *pStrPassword); int SqlQuery(char *pStrSql); int PasStr(int pOper, hcSqlDstInfoT *infCol, long position, unsigned pRecSize, int pCol, long pStr, string** dataRes); int CloseSqlQuery(int pOper); int CloseConnectServer(int pdb); int err = 0; // Код ошибки hcHDB pdb = 0; // Адрес памяти, куда будет записан идентификатор соединения. int pOper = 0; // Адрес памяти, куда будет записан идентификатор оператора. int pCol = 0; // количество колонок long pStr = 0; // количество строк hcRECNO unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . }; файл ComHyTech.cpp #define HYCFG_WIN32 #include "HSCLI.H" #include "ComHyTech.h" using namespace std; ComHyTech::ComHyTech() { } int ComHyTech::ConnectServer(char *pStrConnect, char *pStrLogin, char *pStrPassword) { pStrConnect = "tcpip:/localhost:13000"; // (char*)(void*)Marshal::StringToHGlobalAnsi("");// Сервер pStrLogin = "HTADMIN"; //(char*)(void*)Marshal::StringToHGlobalAnsi("");// Логин pStrPassword = "PASSWORD"; //(char*)(void*)Marshal::StringToHGlobalAnsi("");// Пароль hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации if (err = hcSqlInit(&Init) != 0 ) return err ; // Инициализация клиентской части if (err = hcSqlCheckInit() < 0 ) return err ; // Проверка завершения инициализации if (err = hcSqlAllocConnect(&pdb) != 0 ) return err ; // Создать соединение if (err = hcSqlConnect(pdb, pStrConnect, pStrLogin, pStrPassword) != 0) return err; //Установить связь с СУБД return 0 ; } Добавлено ошибку дает вот на эту строку if (err = hcSqlAllocConnect(&pdb) != 0 ) return err ; // Создать соединение СерьезностьКодОписаниеПроектФайлСтрокаСостояние подавления ОшибкаC2664"hcERR hcSqlAllocConnect(hcHDB *)": невозможно преобразовать аргумент 1 из "cli::interior_ptr<hcHDB>" в "hcHDB *"TestHyTech \Desktop\TestHyTech_class\TestHyTech\ComHyTech.cpp21 |
Сообщ.
#250
,
|
|
|
Попробуй сделать так
hcHDB hDB; if (err = hcSqlAllocConnect(&hDB) != 0 ) return err ; // Создать соединение pdb = hDB; |
Сообщ.
#251
,
|
|
|
чето ошибка поперла
Прикреплённая картинка
Добавлено Цитата Олег М @ Попробуй сделать так ОК делаю Добавлено ОК про Цитата Олег М @ Попробуй сделать так hcHDB hDB; if (err = hcSqlAllocConnect(&hDB) != 0 ) return err ; // Создать соединение pdb = hDB; ОК прошло , Добавлено строка запроса из textBoxa заходит в класс как то криво вот код файл ComHyTech.h #pragma once #define HYCFG_WIN32 #include "HSCLI.H" #include <cstring> #include <stdio.h> #include <string> #include <iostream> #include <memory> #define SIZE_HCSQLDSTINFOT 128 public ref class ComHyTech { int err = 0; // Код ошибки int pdb = 0; // Адрес памяти, куда будет записан идентификатор соединения. int pOper = 0; // Адрес памяти, куда будет записан идентификатор оператора. int pCol = 0; // количество колонок long pStr = 0; // количество строк unsigned pRecSize = 0; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . unsigned cntOp = 0; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". public: ComHyTech( ); int ConnectServer( char* pStrConnect , char * pStrLogin, char * pStrPassword);//char *pStrConnect, char *pStrLogin, char *pStrPassword int SqlQuery(int pdb, char *pStrSql); //int PasStr(int pOper, hcSqlDstInfoT *infCol, long position, unsigned pRecSize, int pCol, long pStr, string** dataRes); //int CloseSqlQuery(int pOper); //int CloseConnectServer(int pdb); }; вот ComHyTech.cpp #define HYCFG_WIN32 #include "ComHyTech.h" ComHyTech::ComHyTech( ) { } int ComHyTech::ConnectServer( char* pStrConnect, char * pStrLogin, char* pStrPassword) { hcHDB hdb = 0; // Адрес памяти, куда будет записан идентификатор соединения. hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации if (err = hcSqlInit(&Init) != 0) return err; // Инициализация клиентской части if (err = hcSqlCheckInit() < 0) return err; // Проверка завершения инициализации if (err = hcSqlAllocConnect(&hdb) != 0) return err; // Создать соединение pdb = hdb; if (err = hcSqlConnect(pdb, pStrConnect, pStrLogin, pStrPassword) != 0) return err; //Установить связь с СУБД return pdb; } int ComHyTech::SqlQuery(int pdb, char *pStrSql) { int pOperTemp; unsigned int cntOpTemp; //pStrSql = "fix all; select * from CITY"; //(char*)(void*)Marshal::StringToHGlobalAnsi("");// поле SQL if (err = hcSqlAllocStmt(pdb, &pOperTemp) != 0) return err; // Создать оператор pOper = pOperTemp; if (err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)1, 0) != 0) return err; // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях if (err = hcSqlExecDirect(pOper, pStrSql) != 0) return err; // Выполняем SQLзапрос //if (err = hcSqlNumResultCols(pOper, &pCol) != 0) return err; // Получить количество колонок результата //if (err = hcSqlRowCount(pOper, &pStr) != 0) return err; // Получить количество строк результата //if (err = hcSqlOpenResults(pOper, &pRecSize) != 0) return err; // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" if (err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * SIZE_HCSQLDSTINFOT, &cntOpTemp) != 0) return err;// Получить информацию об операторе cntOp = cntOpTemp; return pOper ; } Добавлено вот нажатие кнопки private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { ComHyTech Konekt1; int pdb = 0; int pOper = 0; char *pStrConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox1->Text );// Сервер char *pStrLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox2->Text);// Логин char *pStrPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text);// Пароль pdb = Konekt1.ConnectServer( pStrConnect, pStrLogin, pStrPassword) ; pOper = Konekt1.SqlQuery(pdb, (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text )); textBox5->AppendText(" pdb = " + pdb + "\r\n"); textBox5->AppendText(" pOper = " + pOper + "\r\n"); } |
Сообщ.
#252
,
|
|
|
Сообщ.
#253
,
|
|
|
Оппа пошло заменил
pOper = Konekt1.SqlQuery(pdb, (char*)(void*)Marshal::StringToHGlobalAnsi( textBox4->Text )); на pOper = Konekt1.SqlQuery(pdb, (char*)(void*)Marshal::StringToHGlobalAnsi( richTextBox1->Text )); и оно пошло Добавлено конечно класс у меня написан как курица лапой , некоторых вещей я еще не совсем догоняю , но если поможете постараюсь за пару дней перейти к DLL-ке |
Сообщ.
#254
,
|
|
|
Цитата kms @ постараюсь за пару дней перейти к DLL-ке Что-то я упустил. А зачем тебе вообще здесь ДЛЛка? |
Сообщ.
#255
,
|
|
|
подскажите , при нажатии на кнопку
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { ComHyTech Konekt1; int pOper = 0; char *pStrConnect = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox1->Text); // Сервер char *pStrLogin = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox2->Text); // Логин char *pStrPassword = (char*)(void*)Marshal::StringToHGlobalAnsi(textBox3->Text); // Пароль int pdb = Konekt1.ConnectServer( pStrConnect, pStrLogin, pStrPassword ) ; pOper = Konekt1.SqlQuery(pdb , (char*)(void*)Marshal::StringToHGlobalAnsi( richTextBox1->Text )); textBox5->AppendText(" pdb2 = " + pdb + "\r\n"); textBox5->AppendText(" pOper = " + pOper + "\r\n"); } как мне построить заполнение нужных переменных из класса, я предпологал что параметрами в функцию передаю ссылки но как то у меня не получаеться делаю напрмер вот так , в обработчике клика по кнопке int ИдентификаторОператора = 0; pOper = Konekt1.SqlQuery( &ИдентификаторОператора, pdb , (char*)(void*)Marshal::StringToHGlobalAnsi( richTextBox1->Text )); естественно что не так (руские буквы переменной это для внимания) Добавлено Цитата Олег М @ Что-то я упустил. А зачем тебе вообще здесь ДЛЛка? так я же хочу сделать конектор для HyTech , чтобы потом люди могли делать хоть че угодня , потом я хочу сделать Админку и при том DLL-ка пойдет уже под любой язык Добавлено сначала я естественно хочу разобраться с классом, а потом уже перейти к построению обертки DLL-ки |
Сообщ.
#256
,
|
|
|
Цитата Олег М @ Что-то я упустил. А зачем тебе вообще здесь ДЛЛка? На сколько я понял, он хочет сделать морду на WPF, а саму логику работы с базой на С++(темболее что база у него вообще на С, а WPF - это .NET). Тут без DLL, если делать по нормальному и правильно - не обойтись. Но вот теперь я не уверен что он хочет морду на WPF, потому что упрямо пишет морду на C++/CLI, в этом случае - dll, я тоже считаю, что не нужна. Цитата kms @ как мне построить заполнение нужных переменных из класса, я предпологал что параметрами в функцию передаю ссылки но как то у меня не получаеться делаю напрмер вот так , в обработчике клика по кнопке Я лично не понял вопроса. Опиши более конкретнее что у тебя не получается. Какие ссылки ты передаешь и куда? Цитата kms @ делаю напрмер вот так , в обработчике клика по кнопке CollapsedWrap disabledLine numbers off int ИдентификаторОператора = 0; pOper = Konekt1.SqlQuery( &ИдентификаторОператора, pdb , (char*)(void*)Marshal::StringToHGlobalAnsi( richTextBox1->Text )); Так вообще делать неправильно. Ты вот расскажи, кто тебе посоветовал сделать двойное преобразование типов ? Что это за выверт такой? Цитата kms @ (char*)(void*)Marshal::StringToHGlobalAnsi( richTextBox1->Text ) Откуда ты его взял? Почитай для начала вот эту статью -> https://msdn.microsoft.com/ru-ru/library/hh279667.aspx Потом поясни, что конкретно не получается сделать? Добавлено kms, ты сейчас пишешь на промежуточном ЯП от майкрософта, который поддерживается только майкрософтом и в основном нужен для написания прокладок между нативным C/C++ кодом и управляемым .NET кодом. Понимаешь? Поначалу, когда у тебя не получалось прочитать данные из БД, я лично, не знакю как Олег М, закрывал глаза. Но теперь - тебе нужно определиться. Или ты на этой прокладке пишешь свой класс/набор функций, и по сути вопрос темы закрыт. Или ты пишешь на С++, который С++, а не С++/CLI. Еще можешь сразу импортировать функции из БД в .NET среду, минуя написания логики на С++, а сразу прям в .NET писать класс оболочку над этими функциями(примитивный пример можешь посмотреть тут-> https://habrahabr.ru/sandbox/46381/ ), но тогда это не логично обсуждать этот вопрос в этом разделе. Добавлено Вообще я предлагал тебе сделать класс отдельный, на чистом С++, тот который не CLI, выложить сюда свой класс - для того, что бы мы его посмотрели, и указали на твои ошибки, или при написании класса если возникнут вопросы - помочь в решении этих вопросов. Потом экспортировать этот класс в DLL. И вот у тебя получилась бы dll, с полным функционалом для работы с БД, написанная на С++, а уже потом, ты бы в .NET разделе создал бы тему про то, как эту dll подключить к твоему проекту, который ГУИ на WPF(или на чем там?) и как ее там использовать. Но это же уже другой вопрос. Мы тут в этой теме скоро по количеству страниц обгоним некоторые темы в холиварах. Добавлено Цитата kms @ pOper = Konekt1.SqlQuery(pdb, (char*)(void*)Marshal::StringToHGlobalAnsi( richTextBox1->Text )); и оно пошло Странно, а почему ты не написал вот так? pOper = Konekt1.SqlQuery(pdb, (char*)(void*)(int*)(double*)(float*)(unsigned long int*)Marshal::StringToHGlobalAnsi( richTextBox1->Text )); Так бы тоже пошло, наверное |
Сообщ.
#257
,
|
|
|
Цитата KILLER @ На сколько я понял, он хочет сделать морду на WPF, а саму логику работы с базой на С++(темболее что база у него вообще на С, а WPF - это .NET). Тут без DLL, если делать по нормальному и правильно - не обойтись. точно точно , мысли прочитал Добавлено Цитата KILLER @ потому что упрямо пишет морду на C++/CLI, в этом случае - dll, я тоже считаю, что не нужна. не не не , на C++/CLI это я сейчас делаю для того чтобы разобраться с механикой всей конструкции СУБД , чтобы DLL-ку нормальную сделать , а так вооще в планах перейти к изучению ClickHouse там исходники открыты |
Сообщ.
#258
,
|
|
|
Цитата KILLER @ он хочет сделать морду на WPF, а саму логику работы с базой на С++ Цитата KILLER @ В принципе, есть ещё возможность воспользоваться каналом (трубой). Но вряд ли это проще. Тут без DLL, если делать по нормальному и правильно - не обойтись. |
Сообщ.
#259
,
|
|
|
Цитата KILLER @ На сколько я понял, он хочет сделать морду на WPF, а саму логику работы с базой на С++(темболее что база у него вообще на С, а WPF - это .NET). Тут без DLL, если делать по нормальному и правильно - не обойтись. Но вот теперь я не уверен что он хочет морду на WPF, потому что упрямо пишет морду на C++/CLI, в этом случае - dll, я тоже считаю, что не нужна. да лучше написать под эту СУБД обертку на чистом С++ и создать dll или статик lib, и потом морду на чем хочет, я бы выбрал естесно MFC но и связка WPF + C# нормуль С++/CLI + Windows Forms ИМХО для переноса старых проектов С++ на .NET и для извращенцев |
Сообщ.
#260
,
|
|
|
Цитата Cfon @ да лучше написать под эту СУБД обертку на чистом С++ и создать dll да да да я же так и хочу , и так пытаюсь сделать только к MFC у меня как бы не устраивает, все таки WPF для этого и предназначен что бы рисовать интерфейсы Добавлено Цитата amk @ В принципе, есть ещё возможность воспользоваться каналом (трубой). Но вряд ли это проще. подскажите а что за труба |
Сообщ.
#261
,
|
|
|
Цитата kms @ только к MFC у меня как бы не устраивает, все таки WPF для этого и предназначен что бы рисовать интерфейсы ну да WPF в плане гуя по круче, но я и не говорю не юзать его, юзай тока на C# |
Сообщ.
#262
,
|
|
|
Цитата kms @ int ConnectServer( char* pStrConnect , char * pStrLogin, char * pStrPassword);//char *pStrConnect, char *pStrLogin, char *pStrPassword int SqlQuery(int pdb, char *pStrSql); я выполняю эти функции , а как дальше идти передавать infCol, position, pRecSize, pCol, pStr, dataRes Добавлено Цитата Cfon @ юзай тока на C# да да я так и хотел Добавлено Цитата KILLER @ Ты вот расскажи, кто тебе посоветовал сделать двойное преобразование типов ? Что это за выверт такой? Цитата kms @ Вчера, 11:35 (char*)(void*)Marshal::StringToHGlobalAnsi( richTextBox1->Text ) Откуда ты его взял? я даже не не знаю само как то получилось, бес попутал |
Сообщ.
#263
,
|
|
|
Цитата kms @ подскажите а что за труба Речь про Pipes https://msdn.microsoft.com/en-us/library/wi...0(v=vs.85).aspx Честно говоря, я несколько раз пробовал эти пайпы, и всякий раз оказывалось, что shared memory всё равно проще, а сокеты - гибче. |
Сообщ.
#264
,
|
|
|
Цитата Mr.Delphist @ Трубы хороши там, где надо иметь смешанный интерфейс консоль/GUI. Тогда можно ГУЙ написать над консольным прилложением, никак это консольное под ГУЙ не подстраивая. всякий раз оказывалось, что shared memory всё равно проще, а сокеты - гибче. |
Сообщ.
#265
,
|
|
|
amk, ну где-то так, да. Когда есть явное разделение ролей "ведущий-ведомый".
|
Сообщ.
#266
,
|
|
|
Цитата KILLER @ Ты вот расскажи, кто тебе посоветовал сделать двойное преобразование типов ? Что это за выверт такой? Цитата kms @ Вчера, 11:35 (char*)(void*)Marshal::StringToHGlobalAnsi( richTextBox1->Text ) вот я вспомнил почему я так сделал, если убираю (void*) то вылетает ошибка СерьезностьКодОписаниеПроектФайлСтрока ОшибкаC2440приведение типов: невозможно преобразовать "System::IntPtr" в "char *"RudderHyTech rudderhytech\MyForm.h1404 если убираю (char*) то тогда ошибка СерьезностьКодОписаниеПроектФайлСтрока ОшибкаC2440инициализация: невозможно преобразовать "void *" в "char *"RudderHyTech \MyForm.h1404 вот тогда только у меня вот так пошло void *strConnect = (void*)Marshal::StringToHGlobalAnsi(textBox3->Text );// Сервер if(err = hcSqlConnect(pdb, (char*)strConnect, strLogin, strPassword) != 0) textBox2->AppendText("Ошибка Установить связь с СУБД \r\n"); //Установить связь с СУБД но в этом варианте тоже два преобразования из textBox3->Text в void* и из void* в char* Добавлено Цитата KILLER @ Откуда ты его взял? вот вспомнил https://support.microsoft.com/ru-ru/help/31...har-in-visual-c там второй метод |
Сообщ.
#267
,
|
|
|
Цитата kms @ вот вспомнил https://support.microsoft.com/ru-ru/help/31...har-in-visual-c там второй метод Аааа, ну понятно, это такие правила преобразования типов из за ущербности языка видимо в С++/CLI. Именно по этому на нем как можно меньше кода нужно писать. И вообще по возможности избегать его. Но, если класс экспортировать в DLL, то скорее всего из того же C# врятли такой класс загрузишь из DLL, и вот тут на помощь придет C++/CLI, в принципе только за этим он и нужен. Так что бросай на нем писать свою БД, переходи или на чистый С++ или на C#. Потому как такой трешь видимо в С++/CLI и нужен только. |
Сообщ.
#268
,
|
|
|
Цитата KILLER @ переходи или на чистый С++ или на C# если делать сразу на С# то еще трудней будет сделать обертку на "API клиентской части СУБД HyTech 2.5 (hscli)" делаю новую тему , если есть возможность помогите |
Сообщ.
#269
,
|
|
|
Цитата KILLER @ если класс экспортировать в DLL, то скорее всего из того же C# врятли такой класс загрузишь из DLL, и вот тут на помощь придет C++/CLI, в принципе только за этим он и нужен. на 100% согласен |
Сообщ.
#270
,
|
|
|
Цитата KILLER @ переходи или на чистый С++ или на C#. сейчас уже тему на на С++ сделана , сейчас еще сделаю на C# |
Сообщ.
#271
,
|
|
|
Всем большое спасибо, я думаю тему можно закрыть
|
Сообщ.
#272
,
|
|
|
Думаю, тут можно поставить галку "Вопрос решён" и дать ссылку на C#-тему
|
Сообщ.
#273
,
|
|
|
Цитата Mr.Delphist @ Думаю, тут можно поставить галку "Вопрос решён" и дать ссылку на C#-тему ОК полностью согласен, я просто не заметил что можно ставить галочку"Вопрос решен" так же хочу подвести черту , по данному вопросу вот получившийся исходник #define HYCFG_WIN32 #include "hscli.h" #include <iostream> #include <memory> #define SIZE_HCSQLDSTINFOT 128 int main() { int err = 0 ; // Код ошибки int pdb = 0 ; // Адрес памяти, куда будет записан идентификатор соединения. int pOper = 0 ; // Адрес памяти, куда будет записан идентификатор оператора. int pCol = 0 ; // количество колонок long pStr = 0 ; // количество строк hcRECNO unsigned cntOp = 0 ; // Размер считанной информации в байтах, в ф-ции "Получить информацию об операторе". unsigned pRecSize = 0 ; // Размер читаемой записи в байтах, в ф-ции "Открытие результатов для чтения" . hcSqlParmT Init = { sizeof(Init) }; // Адрес структуры с параметрами инициализации err = hcSqlInit(&Init) ; // Инициализация клиентской части err = hcSqlCheckInit() ; // Проверка завершения инициализации err = hcSqlAllocConnect(&pdb) ;// Создать соединение err = hcSqlConnect(pdb, "tcpip:/localhost:13000", "HTADMIN", "PASSWORD") ; //Установить связь с СУБД err = hcSqlAllocStmt(pdb, &pOper) ; // Создать оператор err = hcSqlSetStmtAttr(pOper, HSCLI_ATTR_FLD_VERBOSE, (void*)1, 0) ; // ф-ция "Изменение параметров оператора" получаем расширенную инф.о полях err = hcSqlExecDirect(pOper, "fix all;select * from TAB4;"); // Выполняем SQLзапрос err = hcSqlNumResultCols(pOper, &pCol) ; // Получить кол-во колонок результата err = hcSqlRowCount(pOper, &pStr) ; // Получить кол-во строк результата err = hcSqlOpenResults(pOper, &pRecSize) ; // Открытие результатов для чтения hcSqlDstInfoT *infCol = new hcSqlDstInfoT[pCol]; // Структура "Информация о колонках результата" err = hcSqlGetStmtAttr(pOper, HSCLI_STMT_DST_INFO, 0, infCol, pCol * SIZE_HCSQLDSTINFOT, &cntOp) ;// Получить информацию об операторе char bufOut[1024]; unsigned cntOut = 0; for (long i = 0; i < pStr; i++)//идем по строкам { const auto err = hcSqlReadResults(pOper, i, bufOut, sizeof(bufOut), &cntOut);// Чтение результатов char *p = bufOut; for (size_t j = 0; j < cntOut / sizeof(hcSqlAliasInfoT); ++j)// идем по колонкам { switch (infCol[j].type)// в зависимости от типа колонки преобразовываем в соответствующий тип { case HSCLI_ET_CHAR: // 0 Массив символов длиной не более заданной { std::string s(p, infCol[j].len); std::cout << s.c_str() << " "; } break; case HSCLI_ET_ARRA: // 1 Массив байтов заданной длины std::cout << *reinterpret_cast<unsigned char *>(p) << " "; break; case HSCLI_ET_BYTE: // 2 Элемент - unsigned char (короткое целое) short std::cout << *reinterpret_cast<unsigned char *>(p) << " "; break; case HSCLI_ET_INTR: // 3 Элемент - signed short std::cout << *reinterpret_cast<signed short *>(p) << " "; break; case HSCLI_ET_WORD: // 4 Элемент - unsigned short std::cout << *reinterpret_cast<unsigned short *>(p) << " "; break; case HSCLI_ET_DATE: // 5 Дата - unsigned short std::cout << *reinterpret_cast<unsigned short *>(p) << " "; break; case HSCLI_ET_NMBR: //6 Номер - 3-х байтовое целое без знака // std::cout << *reinterpret_cast< *>(p); break; case HSCLI_ET_LONG: //7 Элемент - long int std::cout << *reinterpret_cast<long int *>(p) << " "; break; case HSCLI_ET_DWRD: // 8 Элемент - unsigned long int в БД это dword std::cout << *reinterpret_cast<unsigned long int *>(p) << " "; break; case HSCLI_ET_FLOA: // 9 Элемент - float std::cout << *reinterpret_cast<float *>(p) << " "; break; case HSCLI_ET_CURR: // 10 Деньги (double) std::cout << *reinterpret_cast<double *>(p) << " "; break; case HSCLI_ET_DFLT: // 11 Элемент - double std::cout << *reinterpret_cast<double *>(p) << " "; break; case HSCLI_ET_QINT: // 12 Элемент - signed __int64 std::cout << *reinterpret_cast<signed __int64 *>(p) << " "; break; case HSCLI_ET_QWRD: // 13 Элемент - unsigned __int64 std::cout << *reinterpret_cast<unsigned __int64 *>(p) << " "; break; } p += infCol[j].len; } std::cout << std::endl; } hcSqlCloseResults(pOper); // Закрытие доступа к результатам hcSqlFreeConnect(pdb); // Освободить соединение hcSqlDone(); // Завершение работы std::system("pause"); } Добавлено Цитата Mr.Delphist @ и дать ссылку на C#-тему сразу на С# не получится потому что выяснилось однозначно надо сначала сделать прослойку на С++/CLI |
Сообщ.
#274
,
|
|
|
Эх , как жаль , на С/С++ все так хорошо пошло , а на C# ни кто не хочет помочь
|
Сообщ.
#275
,
|
|
|
char bufOut[1024]; auto err = hcSqlReadResults(pOper, i, bufOut, sizeof(bufOut), &cntOut); максимальный буфер чтения у hcSqlReadResults 65535 надо выносить эту функцию из общего цикла чтения данных и читать блоками по 65535, пока не будет достигнут конец &pRecSize*&pStr по одной строке читать, это долго. |