17

出现了一种情况,我需要在 SQL 语句的上下文中执行 base 36 到 base 10 的转换。Oracle 9 或 Oracle 10 中似乎没有内置任何东西来解决这类问题。我的 Google-Fu 和 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 的东西。 编辑 - 这是倒退......给定01Z将其翻译为71。

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

谢谢

邪恶的。

4

2 回答 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)
         )
)
于 2010-04-02T19:28:14.227 回答
4

对于 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 的字符串,您需要向位置向量添加更多值。

于 2015-01-15T00:51:54.960 回答