是一种更好,更短的方式来执行此代码:
/*Replace all letters by their respective ASCII code - 55*/
as_iban := REPLACE(as_iban, 'A', '10');
as_iban := REPLACE(as_iban, 'B', '11');
as_iban := REPLACE(as_iban, 'C', '12');
as_iban := REPLACE(as_iban, 'D', '13');
as_iban := REPLACE(as_iban, 'E', '14');
as_iban := REPLACE(as_iban, 'F', '15');
as_iban := REPLACE(as_iban, 'G', '16');
as_iban := REPLACE(as_iban, 'H', '17');
as_iban := REPLACE(as_iban, 'I', '18');
as_iban := REPLACE(as_iban, 'J', '19');
as_iban := REPLACE(as_iban, 'K', '20');
as_iban := REPLACE(as_iban, 'L', '21');
as_iban := REPLACE(as_iban, 'M', '22');
as_iban := REPLACE(as_iban, 'N', '23');
as_iban := REPLACE(as_iban, 'O', '24');
as_iban := REPLACE(as_iban, 'P', '25');
as_iban := REPLACE(as_iban, 'Q', '26');
as_iban := REPLACE(as_iban, 'R', '27');
as_iban := REPLACE(as_iban, 'S', '28');
as_iban := REPLACE(as_iban, 'T', '29');
as_iban := REPLACE(as_iban, 'U', '30');
as_iban := REPLACE(as_iban, 'V', '31');
as_iban := REPLACE(as_iban, 'W', '32');
as_iban := REPLACE(as_iban, 'X', '33');
as_iban := REPLACE(as_iban, 'Y', '34');
as_iban := REPLACE(as_iban, 'Z', '35');
上面的代码将字符串的所有上部字符转换为相应的ASCII代码编号。但这不是正确的方法,但我无法想出另一种方法。
我尝试了类似
的内容FOR i in 1..LENGTH(as_iban)
LOOP
select regexp_replace(as_iban,'['||substr(as_iban,i,1)||']', ASCII(regexp_substr(as_iban,'['||substr(as_iban,i,1)||']')) - 55) into as_iban FROM dual;
END LOOP;
答案 0 :(得分:5)
我想你可能正在寻找这样的东西:
CREATE OR REPLACE FUNCTION FUBAR_STR(in_str VARCHAR2) RETURN VARCHAR2 AS
out_str VARCHAR2(4000) := '';
BEGIN
FOR i IN 1..LENGTH(in_str) LOOP
out_str := out_str || TO_CHAR(ASCII(SUBSTR(in_str,i,1)) - 55);
END LOOP;
RETURN out_str;
END FUBAR_STR;
所以当你跑:
select fubar_str('abcd') from dual;
你得到:42434445。
这是可以使用的可逆,更安全的。
CREATE OR REPLACE FUNCTION FUBAR_STR(in_str VARCHAR2) RETURN VARCHAR2 AS
out_str VARCHAR2(32676) := '';
BEGIN
FOR i IN 1..LEAST(LENGTH(in_str),10892) LOOP
out_str := out_str || LPAD(TO_CHAR(ASCII(SUBSTR(in_str,i,1)) - 55),3,'0');
END LOOP;
RETURN out_str;
END FUBAR_STR;
所以当你跑:
select fubar_str('abcd') from dual;
你得到:042043044045。
因为我今晚真的很无聊:
CREATE OR REPLACE FUNCTION UNFUBAR_STR(in_str VARCHAR2) RETURN VARCHAR2 AS
out_str VARCHAR2(10892) := '';
BEGIN
FOR i IN 0..(((LENGTH(in_str) - MOD(LENGTH(in_str),3))/3) - 1) LOOP
out_str := out_str || CHR(TO_NUMBER(LTRIM(SUBSTR(in_str,(i * 3) + 1,3),'0')) + 55);
END LOOP;
RETURN out_str;
END UNFUBAR_STR;
所以当你跑:
select unfubar_str('042043044045') from dual;
你得到:abcd。
答案 1 :(得分:2)
这是一种在一个命令中执行此操作的方法:
select listagg((column_value).getstringval() - 55)
within group (order by 1) as output
from xmltable(regexp_replace(dump('abcd'), '.*: (\d.*)$', '\1'));
输出:
说明:
从dump()
获取输出并使用regexp_replace()
从输出中提取以逗号分隔的ASCII值列表(转储输出包括以逗号分隔的传入数据的ASCII值列表) 。使用xmltable()
将逗号分隔列表转换为行。这是必需的,因为我们需要处理每一行,从每个需求的值减去55,使用listagg()
在将55减去一个字符串后转换结果。
有关详细信息,请参阅:
dump():http://docs.oracle.com/cd/B28359_01/server.111/b28286/functions048.htm#SQLRF00635 regexp_replace():http://docs.oracle.com/cd/B28359_01/server.111/b28286/functions137.htm#SQLRF06302 xmltable():http://docs.oracle.com/cd/B28359_01/server.111/b28286/functions240.htm#SQLRF06232 listagg():http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions089.htm#SQLRF30030