有没有办法在Oracle 10g中将十进制转换为二进制或二进制转换为十进制,而无需先定义函数?我有限制数据库访问(仅限SELECT),我在网上发现的所有解决方案似乎都涉及CREATE FUNCTION
,这对我不起作用。
答案 0 :(得分:2)
如果十六进制足够好,那么TO_CHAR和TO_NUMBER可以工作:
SQL> select to_char(31, '0x') from dual;
TO_
---
1f
SQL> select to_number('1f', '0x') from dual;
TO_NUMBER('1F','0X')
--------------------
31
您也可以使用RAWTOHEX()
和HEXTORAW()
函数进行十六进制到二进制转换。
答案 1 :(得分:1)
专门研究粗糙的SQL益智游戏的Frank Zhou为这个问题设计了一个纯SQL解决方案。您可以在his OraQA site找到它。但要注意:它实际上 gnarly。
<强>更新强>
OraQA的原始链接已被破坏:The Wayback Machine has an archived version here。
答案 2 :(得分:0)
您可以在SQLPlus脚本中执行PL / SQL,如下所示:
declare
procedure bin_2_dec(/*some parameters here*/) is
begin
/*do computation and print result*/
end;
begin
bin_2_dec('11110000');
end;
/
我不确定,但我认为该功能不会在数据库中永久创建,我认为它只会在脚本持续时间内暂时存在,因此可能工作。值得一试,对吗? ;)
或者,如果这不起作用,你可以SELECT ... from dual
进行转换,虽然这可能很尴尬,但只有你知道数字的数量才会起作用 - 也许(如果你知道的话,我会尝试将它放在一起)我可以得到几分钟,如果可能的话。)
答案 3 :(得分:0)
十进制到二进制的粗略但直接的解决方案:
SELECT REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(TO_CHAR (100,'FMxxx'),
'0','0000'),
'1','0001'),
'2','0010'),
'3','0011'),
'4','0100'),
'5','0101'),
'6','0110'),
'7','0111'),
'8','1000'),
'9','1001'),
'A','1010'),
'B','1011'),
'C','1100'),
'D','1101'),
'E','1110'),
'F','1111')
FROM DUAL;
二进制到十进制会比较棘手。您可以使用connect by
将字符串拆分为4个字符的段,以类似的方式转换它们,然后将它们连接在一起(使用connect by
的第二个SYS_CONNECT_BY_PATH
?),但今晚锻炼对我来说有点太乏味了。
第二个想法,这是二进制到十进制的解决方案(我是connect by
问题的傻瓜):
SELECT TO_NUMBER(
REPLACE (
SYS_CONNECT_BY_PATH (octet, '!'),
'!', ''),
'xxxxxx')
FROM (SELECT CASE SUBSTR
(LPAD (a,
CEIL (LENGTH(a)/4)*4, '0'),
(LEVEL-1)*4+1, 4)
WHEN '0000'
THEN '0'
WHEN '0001'
THEN '1'
WHEN '0010'
THEN '2'
WHEN '0011'
THEN '3'
WHEN '0100'
THEN '4'
WHEN '0101'
THEN '5'
WHEN '0110'
THEN '6'
WHEN '0111'
THEN '7'
WHEN '1000'
THEN '8'
WHEN '1001'
THEN '9'
WHEN '1010'
THEN 'A'
WHEN '1011'
THEN 'B'
WHEN '1100'
THEN 'C'
WHEN '1101'
THEN 'D'
WHEN '1110'
THEN 'E'
WHEN '1111'
THEN 'F'
END AS octet,
LEVEL AS seq,
CEIL (LENGTH(a)/4) AS max_level
FROM (SELECT '101010101010101010' AS a
FROM DUAL)
CONNECT BY LEVEL <= CEIL(LENGTH(a)/4))
WHERE LEVEL = max_level
CONNECT BY PRIOR seq = seq-1
此解决方案仅适用于当前编写的一行一行。要使其适用于多行,您需要向最外面的connect by
添加某种唯一标识符。
答案 4 :(得分:0)
我在Oracle中尝试使用CONNECT BY
在简单的SELECT
语句中将十进制转换为二进制。终于得到了理想的输出。你可以使用下面的,它工作正常。
WITH INPUT AS
(SELECT &N AS X FROM DUAL)
SELECT SUM(MOD(FLOOR(X*POWER(0.5,LEVEL-1)),2)*POWER(10,LEVEL-1)) AS
OUTPUT FROM INPUT CONNECT BY POWER(2,LEVEL-1)<=X;