Отображение больших чисел их внешних Баз Данных в SAS.

Всем привет.
logo_08062015

Сколько бы вы не работали с SAS, все равно постоянно приходиться сталкиваться с чем-то новым.

Недавно столкнулся со следующим глюком — SAS некорректно отображает большие числа из внешних баз данных, а именно округляет их.

Давайте проведем эксперимент и посмотрим как SAS будет отображать следующие числа:

  • 1000000000123456789
  • 200000000123456789
  • 30000000123456789
  • 4000000123456789
  • 500000123456789
  • 1000000000123456791
Каждый раз убираем один 0 из числа. Последнее число на 2 больше первого.
Итак добавляем эти все числа в таблицу в Oracle.
Посмотрим как она будет выглядеть:
oracle_1
Теперь давай посмотрим как эта таблица будет выглядеть если открыть ее в SAS:
sas_1

И что мы видим —  то что у нас получилась полная фигня. Все числа (за исключением пятого) исказились. Более того первое и последнее стали одинаковыми, хотя в действительности они разные. Так что будьте внимательны, работая с большими числами.

Оказывается SAS начинает их округлять и искажать если число превышает Number(14).
Будьте внимательны! Так как этот косяк может всплыть уже очень поздно. Например, все числа станут одинаковыми (как в случае с первым и последним нашим числом). А вы даже не будите подозревать в чем дело.
Теперь напрашивается вопрос, что же с этим делать?
И ответ здесь следующий — переводить число в текст в БД и лишь после с ним работать в SAS. Если потребуется то в SAS можно конвертнуть его обратно в число.
В нашем случае выход будет следующим: создать view в Oracle, в котором наше поле будет текстовым:
view

В Oracle данные будут выглядеть следующим образом.
view_select
Тогда мы будем в SAS передавать текстовое значение.
Откроем созданную View в SAS и увидим:
sas_view
Все числа отображаются корректно.
С уважением,
Николай.

Отображение больших чисел их внешних Баз Данных в SAS.: 7 комментариев

  1. Саша, в данном случае все нормально. Просто 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.

  2. Алексей, пока что это лишь попытки. Тип называется 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 языком?

  3. Свежая проблемка. Хранился 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;

Добавить комментарий

Войти с помощью: 

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.