仅使用SQL将36进制转换为10进制

17

我遇到了一个情况,需要在SQL语句的上下文中执行从36进制转换成10进制的操作。似乎Oracle 9或者Oracle 10都没有内建的函数来解决这种问题。我的谷歌搜索和AskTom都建议创建一个PL/SQL函数来解决这个任务,但是目前对我来说不是一个选项。我正在寻求有关如何解决此问题的建议。

为了更形象地描述:

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

我正在寻找一种方法,根据输入的01Z来计算值71。 EDIT - 这是相反的...给定01Z将其翻译成71。

作为贿赂,每个有用的答案都会获得一个免费的赞。

谢谢

恶意。


2
我只是很好奇(我一直想找一个借口使用不同的基数来存储数据); 基数36的数据用于什么? - David Murdoch
1
我很好奇为什么这必须在SQL中完成,这并不是很常见的做法。 - Georg Schölly
3
36进位的优点在于,您可以使用具有有限键盘的嵌入式设备进行输入。然后,将其解释为36进位而不是字符串更有效,因为尺寸更小,而且您可以使用默认函数进行计算。 - Henri
1
+1,这是我最近看到的比较有趣的问题之一。 - DCookie
@david 这是一个来自传统系统的唯一标识符。把它看作是一个编码序列号。 @georg 这是一个政治问题。选择你的战斗和所有这些。 @dcookie 谢谢... - EvilTeach
2个回答

27
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)
         )
)

1
+1,太棒了!对使用connect by level语法的示例做得非常好。 - DCookie
是的。请用一个case语句替换base36字符串。谢谢Dave。 - EvilTeach

6

对于T-SQL,以下逻辑将执行上面Oracle代码所做的任务。这是通用的解决方案,支持从Base-X到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)

如果要在其他基础上使用,请使用以下命令:

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

或者

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

请注意,为了支持长度大于6的字符串,您需要向位置向量添加更多的值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接