Здравствуйте, уважаемые...
Хочу поделится с вами проблемой. Поможите добрым советом.
Работаю с ODBC API. Для определения параметров поля вызываю функцию SQLDescribeCol — в параметре #6 "DataTypePtr" получаю тип 2. Из Sql.h я понял что это SQL_NUMERIC. Затем передавая этот тип в функцию SQLGetData получаю в RETCODE -1, а значение поля 0. Поле числовое. Что я делаю не так?
Здравствуйте op, вы писали:
op>Здравствуйте VVV, вы писали:
VVV>>Здравствуйте Аноним, вы писали:
VVV>>1. проверьте версию ODBC — SQL_C_NUMERIC появилась только в ODBC 3.0 (до этого SQL_NUMERIC можно было брать через SQL_C_CHAR)
VVV>>2. проверьте, что выборка не пуста и курсор установлен на запись (record), т.е. был выполнен какой-нибудь Fetch или SetPos
VVV>>3. проверьте, что передаёте длину и указатель структуры
VVV>>struct tagSQL_NUMERIC_STRUCT {
VVV>> SQLCHAR precision;
VVV>> SQLSCHAR scale;
VVV>> SQLCHAR sign;
VVV>> SQLCHAR val[SQL_MAX_NUMERIC_LEN];
VVV>>} SQL_NUMERIC_STRUCT;
op>Объясни пожалуйста, что делатьс этим SQL_NUMERIC_STRUCT и почему если поле числовое SQLDescribeCol — в параметре "DataTypePtr" возвращает 2?
Дело в том, что базы данных имеют свои собственные (внутренние) типы данных, которые в sql.h задаются так:
/* Standard SQL datatypes, using ANSI type numbering */
#define SQL_CHAR 1
#define SQL_NUMERIC 2
#define SQL_DECIMAL 3
#define SQL_INTEGER 4
#define SQL_SMALLINT 5
#define SQL_FLOAT 6
#define SQL_REAL 7
#define SQL_DOUBLE 8
#define SQL_VARCHAR 12
как на самом деле они физически хранятся внутри базы знают только разработчики базы и драйвера, теперь, чтобы получить данные из базы мы должны указать в какой тип языка C его преобразовать, для этого служат константы SQL_C_*, т.е. при запросе данных драйвер смотрит тип данных в базе, смотрит может ли его сконвертить в запрошенный сишный тип данных и, если это возможно, то конвертит и возвращает ок, если невозможно, то говорит еррор. Самым универсальным типом при преобразовании является SQL_C_CHAR (т.е. просто строка), практически любой тип (кроме OLE) можно сконвертить в текст и обратно из текста. В хидерах ODBC можно найти как мапируются C типы на SQL типы.
/* C datatype to SQL datatype mapping SQL types
------------------- */
#define SQL_C_CHAR SQL_CHAR /* CHAR, VARCHAR, DECIMAL, NUMERIC */
#define SQL_C_LONG SQL_INTEGER /* INTEGER */
#define SQL_C_SHORT SQL_SMALLINT /* SMALLINT */
#define SQL_C_FLOAT SQL_REAL /* REAL */
#define SQL_C_DOUBLE SQL_DOUBLE /* FLOAT, DOUBLE */
#if (ODBCVER >= 0x0300)
#define SQL_C_NUMERIC SQL_NUMERIC
#endif /* ODBCVER >= 0x0300 */
...
В Вашем случае (если так прямо необходимо использовать SQL_NUMERIC) можно использовать SQL_C_CHAR для получения текстового представления поля
SDWORD cbValue;
char buf[256];
SQLGetData(hstmt, 1, SQL_C_CHAR, buf, sizeof(buf), &cbValue);