2010-04-02 22 views
13

Bir SQL ifadesi bağlamında, temel 10'u temel 10'a dönüştürmem gereken bir durum ortaya çıktı. Bu tür bir şeyi ele almak için Oracle 9 veya Oracle 10'da yerleşik bir şey yok gibi görünüyor. Google-Fu ve AskTom, görevle başa çıkmak için bir pl/sql işlevi oluşturulmasını öneriyor. Bu noktada benim için bir seçenek değil. Bu sorunu çözmemde yardımcı olabilecek bir yaklaşımla ilgili öneriler arıyorum. Ben girdi 01Z dayalı değerini 71, hesaplamak şey arıyorumTaban 36 - SQL kullanarak yalnızca Base 10 dönüşümü

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

... görsel bir forma bu koymak için. DÜZENLEME - bu geriye doğru ... verilen 01Z e çevirme 71.

Rüşvet olarak, her yararlı cevap ücretsiz olarak kabul edilir.

Teşekkürler

Evil.

+1

Sadece merak ediyorum (her zaman veri depolamak için farklı tabanları kullanmak için bir bahane bulmak istedim); Temel 36 verileri ne için kullanılır? –

+1

Ve bunun neden SQL'de yapılması gerektiğini merak ediyorum, bu gerçekten yaygın değil. –

+3

Temel 36'nın avantajı, giriş sağlamak için sınırlı bir klavyeye sahip gömülü bir cihaz kullanabilmenizdir. Daha sonra, string yerine base36 olarak yorumlamak, boyutundan dolayı daha verimlidir ve dahası, varsayılan işlevleri kullanarak hesaplayabilirsiniz. – Henri

cevap

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! Bağlantının düzey sözdizimine göre mükemmel şekilde gösterilmesi. – DCookie

+0

Evet. Base36 dizesini, bir case ifadesiyle değiştirin. Teşekkür ederim Dave. – EvilTeach

2

T-SQL için aşağıdaki mantık, yukarıdaki Oracle kodunun yaptığı görevi gerçekleştirecektir. Bu genel genel çözümdür ve Baz-10 Baz-X destekleyecektir:

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

veya

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

Not desteğine o:

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) 

sadece kullanan diğer bazlar ile kullanmak için 6'dan uzun dizeler konum vektörüne daha fazla değer eklemeniz gerekir.

İlgili konular