如果你只有字符 0123456789ABCDEF 那么你可以使用:
SELECT TO_NUMBER(
'000193CA020008AA190038AA',
'XXXXXXXXXXXXXXXXXXXXXXXX'
) AS from_hex_value
FROM DUAL;
哪些输出:
| FROM_HEX_VALUE |
| ------------------------------------: |
| 1906840079024071083309226 |
如果您有字符 0-9A-Z 并希望将其视为 36 进制字符串,那么您可以创建函数:
CREATE FUNCTION base36_to_number(
value IN VARCHAR2,
-- The value to parse from base 36 to base 10.
width IN INT DEFAULT 0,
-- The width of the substring to consider; 0 is the entire string.
offset IN INT DEFAULT 0
-- The number of widths to offset from the least-significant digit.
) RETURN NUMBER DETERMINISTIC
IS
c CHAR(1);
total NUMBER := 0;
len PLS_INTEGER := COALESCE(LENGTH(value),0);
start_pos PLS_INTEGER;
end_pos PLS_INTEGER;
BEGIN
IF width < 0 THEN
RAISE_APPLICATION_ERROR( -20000, 'Invalid width.' );
ELSIF offset < 0 THEN
RAISE_APPLICATION_ERROR( -20000, 'Invalid offset.' );
ELSIF width = 0 THEN
start_pos := 1;
end_pos := len;
ELSIF width * offset > len THEN
RETURN 0;
ELSIF width * (offset + 1) > len THEN
start_pos := 1;
end_pos := len - width * offset;
ELSE
start_pos := len - width * ( offset + 1 ) + 1;
end_pos := start_pos + width - 1;
END IF;
FOR i IN start_pos .. end_pos LOOP
c := SUBSTR(value,i,1);
total := total * 36
+ CASE
WHEN '0' <= c AND c <= '9'
THEN TO_NUMBER(c)
WHEN 'A' <= c AND c <= 'Z'
THEN ASCII(c) - 55
WHEN 'a' <= c AND c <= 'z'
THEN ASCII(c) - 87
ELSE NULL
END;
END LOOP;
total := total * POWER( 36, width * offset );
RETURN total;
END;
/
然后:
SELECT BASE36_TO_NUMBER('000193CA020008AA190038AA') AS from_base36_value
FROM DUAL;
输出:
| FROM_BASE36_VALUE |
| -------------------------------------------: |
| 16743829188442650222733747166386 |
NUMBER 的最大大小为 38 位十进制数字,并且不能容纳超过 24 个字符的 base-36 数字。如果您的值较大,则需要将其转换为多个数字:
即:
CREATE TABLE table_name ( value ) AS
SELECT '010000AA000001AA020019AA020047AA020138AA020139AA060018AA190016AA' FROM DUAL UNION ALL
SELECT '010000AA000001AA020019AA020047AA020138AA020139AA060019AA190016AA' FROM DUAL UNION ALL
SELECT 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZzzzzzzzzzzzzzzzzzzzzzzzz' FROM DUAL;
然后:
SELECT BASE36_TO_NUMBER( value, 24, 0 ) AS low_value,
BASE36_TO_NUMBER( value, 24, 1 ) AS mid_value,
BASE36_TO_NUMBER( value, 24, 2 ) AS high_value
FROM table_name;
输出:
低值 |中值 |高价值
--------------------------------------: | -------------------------------------------------- ------------------------------------: | -------------------------------------------------- --------------------------------------------------:
34663123071664682325935025837090322 | 777948567801018784511679412336101916888000000000000000000000000000000000 | 30956732997597051152261020650973625595700000000000000000000000000000000000000000000000000000000000
34663123071664682329591184277153298 | 777948567801018784511679412336101916888000000000000000000000000000000000 | 30956732997597051152261020650973625595700000000000000000000000000000000000000000000000000000000000
22452257707354557240087211123792674815 | 504103876157462118901767181449118688664000000000000000000000000000000000000 | 40119919145476304800650528835985676552280000000000000000000000000000000000000000000000000000000000000
db小提琴here