Frage Konvertierung von Base 36 zu Base 10 nur mit SQL


Eine Situation entstanden, wo ich eine Basis 36 durchzuführen, muß 10-Umwandlung zu stützen, in Zusammenhang mit einer SQL-Anweisung. Es scheint nicht alles in Oracle gebaut werden 9 oder 10 Oracle diese Art der Sache zu befassen. Mein Google-Fu und AskTom empfiehlt die Schaffung einer PL / SQL-Funktion mit der Aufgabe zu bewältigen. Das ist für mich an dieser Stelle keine Option. Ich suche nach Vorschlägen für einen Ansatz, der mir helfen könnte, dieses Problem zu lösen.

Um das in eine visuelle Form zu bringen ...

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

Ich suche nach etwas, um den Wert 71 zu berechnen, basierend auf der Eingabe 01Z. EDIT - das ist rückwärts ... gegeben 01Z übersetze es auf 71.

Als Bestechung erhält jede nützliche Antwort eine kostenlose Verbesserung.

Vielen Dank

Böse.


13
2018-04-02 19:17


Ursprung


Antworten:


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

22
2018-04-02 19:28



Für T-SQL führt die folgende Logik die Aufgabe aus, die der obige Oracle-Code ausführt. Dies ist eine generische allgemeine Lösung und unterstützt Base-X bis 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)

Um mit anderen Basen zu verwenden, verwenden Sie einfach:

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

oder

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

Beachten Sie, dass Sie zur Unterstützung von Zeichenfolgen länger als 6 dem Positionsvektor mehr Werte hinzufügen müssen.


2
2018-01-15 00:51