Вопрос про разделитель при "to_number" в oracle?

Leona_Raint

В кратце суть проблемы:
Есть числовое значение типа string.
Есть функция, которая преобразовывает число в сумму прописью.
Соответственно:
Преобразовываем string -> number и передаем в функцию, на выходе получаем число прописью (типа string).
Собственно, загвоздка в том, что, если разделитель на локальном компе стоит ',' то to_number отрабатывает число в формате с разделителем запятой, не смотря на то, что на серваке стоит разделитель '.' И в последствии преобразование в сумму прописью вылетает с ошибкой ...
Как я вижу сию проблему, так это то, что to_number берет значение разделителя из региональных настроек компа на котором выполняеть эти действия, а не сервера. Задавать разделитель жестко, через формат:
1.to_number('123,33','999999999999D99',nls_numeric_characters='.,') - не катит
2.alter session set NLS_NUMERIC_CHARACTERS='.,'; — тоже не помогает
Ну это в кратце ... могу еще что нить добавить, если будут вопросы
3. кстати, replace тоже не помогает
а именно:
summatowords(to_number(replace(SUMMA',','.''9999999999D99',NLS_NUMERIC_CHARACTERS='.,')

pitrik2

кстати, replace тоже не помогает
как это REPLACE может не помочь?
ты явно что-то делаешь не так!

Leona_Raint

replace не помогает, т.к. он это делает в string'е. А окончательное преобразование делает to_number. Который собственно и берет разделитель из региональных настроек. А для типа number применить снова replace - это полная лажа, т.к. применимо только к string

pitrik2

replace не помогает, т.к. он это делает в string'е. А окончательное преобразование делает to_number. Который собственно и берет разделитель из региональных настроек. А для типа number применить снова replace - это полная лажа, т.к. применимо только к string
или я туплю с утра
или ты и вправду невнятно пишешь
но я понял ключевой момент почему replace не катит
потому что он всегда будет точки ставить, а региональные настройки могут быть с запятой

Leona_Raint

Направление мысли правильно
трабла как раз в том, чтобы при обработке to_number получить число, в котором разделитель - '.' а не запятая, в не зависимости от региональных настроек компа на котором запускали запрос с этой функцией
Если поставить в региональных настройках точку, то все будет пучком, но это не вариант ... по крайней мере очень не желательный

sinet

Бррр.
И в последствии преобразование в сумму прописью вылетает с ошибкой...
Ошибка у тебя внутри этой функции.
трабла как раз в том, чтобы при обработке to_number получить число, в котором разделитель - '.' а не запятая
Точка или запятая у тебя появится, если ты обратно to_char будешь делать. Самому NUMBER`у пофигу на региональные настройки.

Leona_Raint

ладно ... вечером напишу или как время будет ... то что функция малек не корректно работает, вполне возможно, НО, она просто заточена под разделитель '.' Ошибка в ней вылетает на стадии определения числа копеек (вернее мин. денежных ед валюты). т.е.
..........
nSumma := round(nSummap,nCRRM);
nA := TRUNC(nSumma);
nX := (nSumma - nA) / nCRCF;
.........
на этапе где определяется nX, если у nSummap будет значение копеек через запятую, то функция вылетит с ошибкой, если будет точка, то все пройдет гуд. Или опять непонятно говорю?

sinet

И с каким кодом ошибки она вылетает?
Если функция заточена под '.', то пропиши внутри неё у функций конвертирования жёстко NLS_NUMERIC_CHARACTERS.

sinet

А summatowords у тебя случайно не VARCHAR2 на входе принимает?

pitrik2

на этапе где определяется nX, если у nSummap будет значение копеек через запятую, то функция вылетит с ошибкой, если будет точка, то все пройдет гуд. Или опять непонятно говорю?
говоришь понятно
только то что говоришь - откровенное вранье
приводи полный код своей функции

Leona_Raint

Собственно до др. функции NumberToWords не доходит, а вылетает с ошибкой:
ORA-01722: invalid number

FUNCTION SummaToWords(
nSummap IN NUMBER,
p_nCurrencyCode IN NUMBER DEFAULT 810,
nMode IN NUMBER DEFAULT 1,
p_sLanguage VARCHAR2 DEFAULT 'RUS'
)
RETURN VARCHAR2
IS
nA NUMBER;
nX NUMBER;
nSumma NUMBER;
str VARCHAR2(254);
sRubName VARCHAR2(100);
sKoopName VARCHAR2(100);
nCurrencyCode NUMBER;
nCRRM number;
nCRCF number;
sKOOP varchar2(20);
sROUND varchar(5);
BEGIN

nCurrencyCode := NVL(p_nCurrencyCode, REPORT2.CurrentCurrency);

BEGIN
select
'||' || NVL(B74FCNA, '||'
'||' || NVL(B74SCNA, '||'
B74CRRM,
B74CRCF
into
sRubName,
sKoopName,
nCRRM,
nCRCF
from
B74
where
B74CURC = nCurrencyCode;
EXCEPTION
WHEN NO_DATA_FOUND THEN
BEGIN
sRubName := '||||';
sKoopName := '||||';
nCRRM :=2;
END;
END;

nSumma := round(nSummap,nCRRM);
nA := TRUNC(nSumma);
nX := (nSumma - nA) / nCRCF;
sKOOP := RPAD('F',nCRRM+1,'0');
sROUND :=RPAD('0',nCRRM,'0');

IF nMode = 0 THEN — ðåçóëüòàò â âèäå 100 ðóáëåé 50 êîïååê
str := to_char(nA)||' '||Declension(nA,sRubName);
str := str || ' ' ||to_char(nX,sROUND)||' '|| Declension(nX, sKoopName);
END IF;

IF nMode = 1 THEN
str := NumberToWords(nA, 'R', sRubName, p_sLanguage);
str := str || ' ' || NumberToWords(nX , sKOOP, sKoopName, p_sLanguage);
END IF;
IF nMode = 2 THEN
str := to_char(nA) || ' ' || NumberToWords(nA, 'R', sRubName, 'M', 2, p_sLanguage);
str := str || ' ' || NumberToWords(nX , sKOOP, sKoopName, p_sLanguage);
END IF;
RETURN str;
END;

Leona_Raint

А summatowords у тебя случайно не VARCHAR2 на входе принимает?
Думаю вопрос снят?

pitrik2

ORA-01722: invalid number
у тебя nCRCF нигде не задается
вот он и говорит что это не намбер

pitrik2

WHEN NO_DATA_FOUND THEN
BEGIN
sRubName := '||||';
зачем так писать?
при объявлении нужно задавать начальные значения
sRubName VARCHAR2(100) := '||||';

Leona_Raint

NCRF задается из таблица select'ом
п.с. функцию разрабы писали и править ее нету полномочий

pitrik2

NCRF задается из таблица select'ом
WHEN NO_DATA_FOUND THEN
- если выборки не было то нифига не задается
п.с. функцию разрабы писали и править ее нету полномочий
во-первых ты ее можешь дебажить
во-вторых ты можешь создать свою процедуру с другим именем но тем же кодом и уже мучать ее

Leona_Raint

1).выборка полюбому будет, т.к. это из таблицы где валюты прописаны
2).дебажить хрен дадут, тем более на боевой запустить (ну, по крайней мере на 90%)
Оставить комментарий
Имя или ник:
Комментарий: