2010-04-02 5 views
13

Powstała sytuacja, w której muszę wykonać konwersję z podstawy 36 na bazę 10, w kontekście instrukcji SQL. Wydaje się, że nie ma nic wbudowanego w Oracle 9 lub Oracle 10, aby rozwiązać ten problem. Moje Google-Fu i AskTom sugerują utworzenie funkcji pl/sql do obsługi tego zadania. To nie jest opcja dla mnie w tym momencie. Szukam sugestii na temat podejścia, które może mi pomóc rozwiązać ten problem.Konwersja od podstawy 36 do bazy 10 przy użyciu tylko języka SQL

Aby umieścić to w formie wizualnej ...

WITH 
Base36Values AS 
(
    SELECT 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' myBase36 FROM DUAL 
), 
TestValues AS 
(
    SELECT '01Z' BASE36_VALUE, 
      71 BASE10_VALUE FROM DUAL 
) 
SELECT * 
FROM Base36Values, 
    TestValues 

szukam czegoś do wyliczenia wartości 71, opartego na wejściu 01Z. EDYCJA - czyli w tył ... biorąc pod uwagę, że 01Z przetłumaczono na 71.

Jako łapówkę, każda przydatna odpowiedź otrzymuje bezpłatną prezentację.

Dzięki

Zło.

+1

Jestem po prostu ciekawy (zawsze chciałem znaleźć wymówkę, aby użyć różnych baz do przechowywania danych); do czego służą dane podstawowe 36? –

+1

I jestem ciekawy, dlaczego to musi być zrobione w SQL, to nie jest tak powszechne. –

+3

Zaletą podstawy 36 jest to, że można używać wbudowanego urządzenia z ograniczoną klawiaturą do wprowadzania danych. Następnie interpretowanie go jako base36 zamiast jako łańcucha jest bardziej wydajne ze względu na rozmiar, a ponadto można go obliczyć przy użyciu domyślnych funkcji. – Henri

Odpowiedz

22
select sum(position_value) from 
(
    select power(36,position-1) * case when digit between '0' and '9' 
            then to_number(digit) 
            else 10 + ascii(digit) - ascii('A') 
           end 
      as position_value 
    from (
      select substr(input_string,length(input_string)+1-level,1) digit, 
       level position 
      from (select '01Z' input_string from dual) 
      connect by level <= length(input_string) 
     ) 
) 
+0

+1, saweeeeeet! Doskonała ilustracja użycia połączenia według poziomu składni. – DCookie

+0

Tak. Zastąp ciąg podstawowy36 instrukcją case. Dziękuję Dave. – EvilTeach

2

W przypadku T-SQL następująca logika wykona zadanie określone powyżej w kodzie Oracle. Jest rodzajowy rozwiązanie ogólne i wspornika podstawowego-X do bazy-10:

select 
    sum(power(base,pos-1) * 
      case when substring(cnv,pos,1) between '0' and '9' then 
       cast(substring(cnv,pos,1) as int) 
      else 10 + ascii(upper(substring(cnv,pos,1))) - ascii('A') end) 
    from (values(reverse('01Z'), 36)) as t(cnv,base) 
     left join (values(1),(2),(3),(4),(5),(6)) as x(pos) 
      on pos <= len(cnv) 

do użycia z innymi zasadami wystarczy użyć:

from (select cnv = reverse('FF'), base=16) as t 

lub

from (select cnv = reverse('101'), base=2) as t 

Należy zauważyć, że do wsparcia ciągi dłuższe niż 6 należy dodać więcej wartości do wektora pozycji.

Powiązane problemy