Всем привет.

Сколько бы вы не работали с SAS, все равно постоянно приходиться сталкиваться с чем-то новым.
Недавно столкнулся со следующим глюком — SAS некорректно отображает большие числа из внешних баз данных, а именно округляет их.
Давайте проведем эксперимент и посмотрим как SAS будет отображать следующие числа:
- 1000000000123456789
- 200000000123456789
- 30000000123456789
- 4000000123456789
- 500000123456789
- 1000000000123456791
Каждый раз убираем один 0 из числа. Последнее число на 2 больше первого.
Итак добавляем эти все числа в таблицу в Oracle.
Посмотрим как она будет выглядеть:

Теперь давай посмотрим как эта таблица будет выглядеть если открыть ее в SAS:
И что мы видим — то что у нас получилась полная фигня. Все числа (за исключением пятого) исказились. Более того первое и последнее стали одинаковыми, хотя в действительности они разные. Так что будьте внимательны, работая с большими числами.
Оказывается SAS начинает их округлять и искажать если число превышает Number(14).
Будьте внимательны! Так как этот косяк может всплыть уже очень поздно. Например, все числа станут одинаковыми (как в случае с первым и последним нашим числом). А вы даже не будите подозревать в чем дело.
Теперь напрашивается вопрос, что же с этим делать?
И ответ здесь следующий — переводить число в текст в БД и лишь после с ним работать в SAS. Если потребуется то в SAS можно конвертнуть его обратно в число.
В нашем случае выход будет следующим: создать view в Oracle, в котором наше поле будет текстовым:
Они уже на первом шаге — в Oracle не корректно отображены: 1000000000123456789 != 1.00000000012346E18
Саша, в данном случае все нормально. Просто PL SQL Developer так отображает большие числа. Если все перевести в текст, как показано ниже, то все отлично. Это действительно косяк SAS Access. Привожу ниже официальный ответ:
When working with numeric datatypes in relational databases, like
Oracle's NUMBER data type, you may discover that SAS rounds the
numeric data when reading. With SAS under Unix and Windows, we store
numeric values as IEEE double-precision floating-point numbers.
Therefore, the decimal precision of a full 8-byte number is
*approximately* 16 decimal digits. It could be 15 or 17, depending on
how the actual value is stored.
When trying to read in a NUMBER(17) or greater for Oracle, SAS will
round this number to 16 digits.
V ds2 sas nachal reshat' etu problemu, mozno opredlit' big integer…
Алексей, пока что это лишь попытки. Тип называется BIGINT.
Попытался я поиграться и ничего не получилось. Выдался worning:
WARNING: BASE driver, creation of a BIGINT column has been requested, but is not supported by the BASE driver. A DOUBLE
PRECISION column has been created instead
Как я понял данными типами еще рано пользоваться.
А ты сам пользуешься DS2 языком?
nachinau izu4at' po nemnozku:) v 9.4 ds2 uze prodaction. tak 4to polzovat'sa uze ne rano:) tu putalsa sozdat' eto s teradatoi?
Пытался сделать с Oracle.
Свежая проблемка. Хранился 20-значный ID. Решал запросом на стороне оракл.
1. Создавал коннект к базе.
2. С помощью провального запроса переводил в текст чз TO_CHAR и далее с помощью оракловских SUBSTR и TO_NUMBER делил на два числовых поля по 8 и 12 символов.
3. И тянул в SAS уже готовую разбитую комбинацию ID.
От прямых текстовых IDшек отказался, так как очень большой объем нужно было тянуть и некоторое время хранить/использовать.
В общем нечто такое (писал в блокноте, возможны текстовые опечатки;) ):
PROC SQL;
connect to oracle as mycon(user=testuser password=testpass path='myorapath');
CREATE WORK.ORATABLE AS
select *
from connection to mycon
(select TO_NUMBER(SUBSTR(TO_CHAR(ID), 1,8)) ID1
,TO_NUMBER(SUBSTR(TO_CHAR(ID), 9,12)) ID2
,TO_CHAR(ID) src_ID
from employees
);
QUIT;