Исходя из правила, что последний символ представляет +1 как A, B +2 как, + 3 как C и т.д .; и -1 как J, -2 как K, -3 как L и т. д., вы можете сделать двухэтапное преобразование. Во-первых заменить последний символ с соответствующей цифрой:
translate(value, 'ABCDEFGHIJKLMNOPQR', '123456789123456789')
Вы могли бы сделать что-то с сравнением ASCII, но простым списком, вероятно, понятнее здесь. А затем преобразовать его в число:
to_number(translate(value, 'ABCDEFGHIJKLMNOPQR', '123456789123456789'))
, а затем умножить на -1, если последний символ был в отрицательном диапазоне:
case when substr(value, -1) >= 'J' then -1 else 1 end
Demo с выборочных значений:
with t (value) as (
select '123C' from dual
union all select '8268D' from dual
union all select '680G' from dual
union all select '269M' from dual
union all select '535R' from dual
)
select value,
to_number(translate(value, 'ABCDEFGHIJKLMNOPQR', '123456789123456789'))
* case when substr(value, -1) >= 'J' then -1 else 1 end as converted
from t;
VALUE CONVERTED
----- ----------
123C 1233
8268D 82684
680G 6807
269M -2694
525R -5259
Вы можете поместить все это в функцию, если вы будете использовать ее много, но ее довольно просто повторить по мере необходимости.
Но вы не указали, как вы представляете последнюю цифру, равную нулю. Если вы используете 'zoned decimal', то вы можете включать те, в translate()
вызова:
translate(value, '{ABCDEFGHI}JKLMNOPQR', '')
Но расчет знака является немного более неловко, как вы не можете просто использовать символьный набор порядка; снова перебором, но ясно, что вы можете просто сравнить последний символ, чтобы решить, если это положительное или отрицательное:
case when substr(value, -1) in ('J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', '}')
then -1 else 1 end
Как функция просто для удовольствия:
create function decode_zoned_decimal(p_value in varchar2) return number is
begin
return to_number(translate(p_value, '{ABCDEFGHI}JKLMNOPQR', ''))
* case when substr(p_value, -1) in ('J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', '}')
then -1 else 1 end;
end;
/
и тестирование с некоторыми дополнительными значениями:
with t (value) as (
select '123C' from dual
union all select '8268D' from dual
union all select '680G' from dual
union all select '269M' from dual
union all select '525R' from dual
union all select '123{' from dual
union all select '123}' from dual
)
select value, decode_zoned_decimal(value) as converted
from t;
VALUE CONVERTED
----- ----------
123C 1233
8268D 82684
680G 6807
269M -2694
525R -5259
123{ 1230
123} -1230
Делитесь более входными данными и желаемым выходом для каждой строки. Это немного неясно для меня сейчас – lad2025
Почему «123C» = 1233? Потому что C - третья буква алфавита, и вы храните вещи в странном смешанном формате? Или это действительно шестнадцатеричное (123C = 4668) или что-то еще? (Не уверен, что это имеет отношение к знаку в любом случае) –
Я предполагаю, что «A», «B», ..., «J» представляют знаковые цифры +1, +2, ..., +0. Как представлены отрицательные знаковые цифры? –