用PL / SQL中的字符串替换每个字母的ASCII码

时间:2014-06-23 22:46:07

标签: sql plsql ascii

是一种更好,更短的方式来执行此代码:

/*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;

2 个答案:

答案 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'));

输出:

<code>enter image description here</code>

说明:

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