2015-11-02 3 views
1

У меня есть таблица, содержащая подписанные числа ('123C' = 1233). Есть ли способ конвертировать эти числа в оператор select в PL/SQL (т.е. +1233), чтобы я мог загрузить их в другую таблицу? Я даже не уверен, как решить этот вопрос.Как конвертировать подписанные числа в Oracle SQL

Спасибо!

+2

Делитесь более входными данными и желаемым выходом для каждой строки. Это немного неясно для меня сейчас – lad2025

+3

Почему «123C» = 1233? Потому что C - третья буква алфавита, и вы храните вещи в странном смешанном формате? Или это действительно шестнадцатеричное (123C = 4668) или что-то еще? (Не уверен, что это имеет отношение к знаку в любом случае) –

+0

Я предполагаю, что «A», «B», ..., «J» представляют знаковые цифры +1, +2, ..., +0. Как представлены отрицательные знаковые цифры? –

ответ

1

Исходя из правила, что последний символ представляет +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 
+0

Очень приятно! Спасибо! – Marianne

+0

@Marianne - Я обновил его, чтобы обработать положительный и отрицательный ноль в качестве последнего символа. Я предположил, что у вас есть такие фигурные скобки. Возможно, вам придется немного изменить его, если это не так. –

+0

Спасибо, Алекс! Работал как шарм. – Marianne

Смежные вопросы