oracle - salida - Conversión de base PL/SQL sin funciones
procedimientos y funciones oracle pl/sql (4)
¿Puedes ejecutar PL / SQL en un script SQLPlus como este?
declare
procedure bin_2_dec(/*some parameters here*/) is
begin
/*do computation and print result*/
end;
begin
bin_2_dec(''11110000'');
end;
/
No estoy seguro, pero no creo que la función se creará permanentemente en la base de datos, creo que solo existirá temporalmente durante la secuencia de comandos, así que esto podría funcionar. Vale la pena intentarlo, ¿verdad? ;)
O si eso no funciona, puedes SELECT ... from dual
a convertir, aunque probablemente sea incómodo y solo funcionará si conoces la cantidad de dígitos, tal vez (intentaré unirlo si puedo obtener unos minutos, y si es posible).
¿Hay alguna manera de convertir decimal a binario, o binario a decimal, en Oracle 10g sin tener que definir primero una función? Tengo acceso limitado a la base de datos (solo SELECCIONAR) y todas las soluciones para esto que he encontrado en línea parecen involucrar CREATE FUNCTION
, lo que no funciona para mí.
Frank Zhou, que se especializa en complicados rompecabezas de SQL, ha ideado una solución SQL pura para este problema. Puede encontrarlo en su sitio OraQA . Pero ten cuidado: es realmente retorcido.
actualizar
El enlace original a OraQA está roto: Wayback Machine tiene una versión archivada aquí .
Si hexadecimal es lo suficientemente bueno, TO_CHAR y TO_NUMBER pueden funcionar:
SQL> select to_char(31, ''0x'') from dual;
TO_
---
1f
SQL> select to_number(''1f'', ''0x'') from dual;
TO_NUMBER(''1F'',''0X'')
--------------------
31
Es posible que pueda usar las RAWTOHEX()
y HEXTORAW()
para hacer la transición hexadecimal a binaria también.
Una solución cruda, pero directa para decimal a binario:
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;
Binario a decimal sería más complicado. Es posible que pueda usar connect by
para dividir la cadena en segmentos de 4 caracteres, convertirlos de manera similar y luego volver a concatenarlos (una segunda connect by
mediante SYS_CONNECT_BY_PATH
?), Pero eso es demasiado tedioso para que funcione. esta noche.
Pensándolo bien, aquí está la solución de Binario a decimal (soy un tonto para connect by
problemas):
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
Esta solución solo funciona para una fila a la vez como está escrita actualmente. Para que funcione con varias filas, necesitarás agregar algún tipo de identificador único a la connect by
más externa connect by
.