|
|
|
DB_VARNUMERIC, SBYTE, Oracle OLE DB
|
|||
|---|---|---|---|
|
#18+
Умные люди, помогите пожалуйста разобраться! Проблема в следующем. Наша программа на С++ может связываться с БД через Oracle OLE DB. И потом пользователи могут отправлять запросы, какие им хочется. Из-за баги в провайдере приходиться сейчас связывать буфера для результатов запроса не как текст (так мы делали раньше), а как тип данных, возвращаемый провайдером после анализа запроса (интерфейс IColumnsInfo). Для некоторых данных (например для вычисляемых значений, типа "SELECT 1/4 FROM DUAL") Oracle возвращает тип DBTYPE_VARNUMERIC. Данные, которые потом провайдер пишет в подготовленный нами буфер, имеют следующую структуру: Typedef struct tagDB_VARNUMERIC { BYTE precision; SBYTE scale; BYTE sign; BYTE val[ 1 ]; } DB_VARNUMERIC; Вот у меня проблема с полем scale. Я его в программе выковыриваю следующим образом: SBYTE scale = ( ( DB_VARNUMERIC * ) rowData )->scale; и потом так использую: adjust *= sign; if (scale < 0) { for( int k = 0 ; k > scale ; k-- ) adjust *= 10; dValue *= adjust; } else { for( int k = 0 ; k < scale ; k++ ) adjust *= 10; dValue /= adjust; } (dValue это double переменная, в которую я перегружаю само число из поля val структуры DB_VARNUMERIC). И всё было бы замечательно, если бы для чисел с експонентой между -128 и -114 не получалась бы полнейшая ерунда. Вот теперь и вопрос: это Oracle мне чушь подсовывает, или я значение scale неправильно выковыриваю? Итак, то, что я получаю: вместо 142 -> -114; 141 -> -115;... ; 128 -> -128; а вот уже начиная с експоненты -113 уже всё в порядке: 127, 126,... Варианты: int scale = ( int )( ( DB_VARNUMERIC * ) rowData )->scale; char scale = ( char )( ( DB_VARNUMERIC * ) rowData )->scale; signed char scale = ( signed char )( ( DB_VARNUMERIC * ) rowData )->scale; Заранее спасибо за идеи!!! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2005, 17:50 |
|
||
|
DB_VARNUMERIC, SBYTE, Oracle OLE DB
|
|||
|---|---|---|---|
|
#18+
Ответ простой: SBYTE scale. Смешно ожидать, что в scale будет стоять 142, если в SBYTE можно только от -128 до 127 представить. Заклинило, звиняйте. Другой вопрос, чего это Oracle OLE DB туда пихает то, что поместиться не может, вместо того чтобы ошибку вернуть :-(((. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2005, 19:15 |
|
||
|
DB_VARNUMERIC, SBYTE, Oracle OLE DB
|
|||
|---|---|---|---|
|
#18+
Lana K.Ответ простой: SBYTE scale. Смешно ожидать, что в scale будет стоять 142, если в SBYTE можно только от -128 до 127 представить. Заклинило, звиняйте. Другой вопрос, чего это Oracle OLE DB туда пихает то, что поместиться не может, вместо того чтобы ошибку вернуть :-(((. Извиняйте, но ведь 142 < 255... Верно? А от -128 до 127 как раз и расположено 256 значений... Вот Оракл и "пихает" туда это значение... А проблема здесь кроется в обработке значений (знаковые / беззнаковые). В случае, если значение знаковое, добавление лишней 1 (переход от 127 к 128) приведет к установке знакового бита в 1, что в свою очередь приведет к значению -128... Скорее всего, Вам надо просто применить преобразование в (unsigned char) (Это как раз и будет интервал от 0 до 255)... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2005, 06:34 |
|
||
|
DB_VARNUMERIC, SBYTE, Oracle OLE DB
|
|||
|---|---|---|---|
|
#18+
Станислав C. Lana K.Ответ простой: SBYTE scale. Смешно ожидать, что в scale будет стоять 142, если в SBYTE можно только от -128 до 127 представить. Заклинило, звиняйте. Другой вопрос, чего это Oracle OLE DB туда пихает то, что поместиться не может, вместо того чтобы ошибку вернуть :-(((. Извиняйте, но ведь 142 < 255... Верно? А от -128 до 127 как раз и расположено 256 значений... Вот Оракл и "пихает" туда это значение... А проблема здесь кроется в обработке значений (знаковые / беззнаковые). В случае, если значение знаковое, добавление лишней 1 (переход от 127 к 128) приведет к установке знакового бита в 1, что в свою очередь приведет к значению -128... Скорее всего, Вам надо просто применить преобразование в (unsigned char) (Это как раз и будет интервал от 0 до 255)... В догонку код, подтверждающий мои слова: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2005, 06:50 |
|
||
|
DB_VARNUMERIC, SBYTE, Oracle OLE DB
|
|||
|---|---|---|---|
|
#18+
Станислав C., спасибо за ответ, но вы не совсем правы. SBYTE - это signed char. Преобразование к unsigned char приведёт просто к искажению данных. Для отрицательных значений будет происходить такая же петрушка, как и с 142 в signed char. Кстати, можете это проверить вашим же кодом. Итак, ещё раз: в структуре могут поместиться значения со scale от -128 до 127, поэтому я считаю поведение Oracle OLE DB ошибочным. Либо исходное число должно было быть округлено так, чтобы его представление в этой структуре было возможным, либо должна возвращаться ошибка. Кстати, майкрософтовский OLE DB провайдер для таких значений возвращает ошибку и пустую структуру. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2005, 15:18 |
|
||
|
DB_VARNUMERIC, SBYTE, Oracle OLE DB
|
|||
|---|---|---|---|
|
#18+
Lana K.Станислав C., спасибо за ответ, но вы не совсем правы. SBYTE - это signed char. Преобразование к unsigned char приведёт просто к искажению данных. Для отрицательных значений будет происходить такая же петрушка, как и с 142 в signed char. Кстати, можете это проверить вашим же кодом. Итак, ещё раз: в структуре могут поместиться значения со scale от -128 до 127, поэтому я считаю поведение Oracle OLE DB ошибочным. Либо исходное число должно было быть округлено так, чтобы его представление в этой структуре было возможным, либо должна возвращаться ошибка. Кстати, майкрософтовский OLE DB провайдер для таких значений возвращает ошибку и пустую структуру. Я все понял правильно. Я лишь отвечаю на Ваш вопрос: автор Вот теперь и вопрос: это Oracle мне чушь подсовывает, или я значение scale неправильно выковыриваю? и объясняю как число, не помещающееся в указанный диапазон (от -128 до 127) все-таки оказывается записанным в переменную... И что это не ошибка, а лишь взгляд на интерпретацию двоичного представления числа... А как Вам поступать дальше (уж коль скоро такая особенность проявилась) - решайте сами... Я же не даю никакого совета... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2005, 15:30 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=33264407&tid=2032772]: |
0ms |
get settings: |
7ms |
get forum list: |
14ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
57ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
2ms |
| others: | 224ms |
| total: | 371ms |

| 0 / 0 |
