2010-04-02 7 views
13

È sorta una situazione in cui è necessario eseguire una conversione da base 36 a base 10, nel contesto di un'istruzione SQL. Non sembra esserci alcun elemento integrato in Oracle 9 o Oracle 10 per risolvere questo genere di cose. Il mio Google-Fu e AskTom suggeriscono di creare una funzione pl/sql per gestire l'attività. Questa non è un'opzione per me a questo punto. Sto cercando suggerimenti su un approccio da adottare che potrebbe aiutarmi a risolvere questo problema.Conversione da 36 a Base 10 utilizzando solo SQL

Per mettere questo in una forma visiva ...

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

Sto cercando qualcosa per calcolare il valore 71, in base ai contributi 01Z. MODIFICA - che è indietro ... dato 01Z traducilo in 71.

Come tangente, ogni risposta utile ottiene un upvote gratuito.

Grazie

male.

+1

Sono solo curioso (ho sempre voluto trovare una scusa per usare basi diverse per memorizzare i dati); a cosa servono i dati di base 36? –

+1

E sono curioso del motivo per cui questo deve essere fatto in SQL, che non è molto comune. –

+3

Il vantaggio della base 36 è che è possibile utilizzare un dispositivo incorporato che ha una tastiera limitata per fornire input. Quindi, interpretandolo come base36 invece come stringa è più efficiente a causa delle dimensioni e inoltre è possibile calcolarlo utilizzando le funzioni predefinite. – Henri

risposta

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! Illustrazione eccellente dell'uso della connessione per sintassi di livello. – DCookie

+0

Sì. Sostituisci la stringa base36 con un'istruzione case. Grazie Dave. – EvilTeach

2

Per T-SQL, la seguente logica eseguirà il compito indicato dal codice Oracle precedente. Si tratta di soluzione generale generica e sosterrà Base-X per Base-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) 

da utilizzare con altre basi basta usare:

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

o

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

Si noti che per il supporto stringhe superiori a 6 è necessario aggiungere più valori al vettore posizione.

Problemi correlati