17

SQLステートメントのコンテキストで、基数36から基数10への変換を実行する必要がある状況が発生しました。この種の問題に対処するためにOracle9またはOracle10に組み込まれているものはないようです。私の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 に答える