平常在支付宝或者银行账户等转账的时候系统为了保护隐私,一般将客户的姓打成 * 号,直接看例子
SQL> --示例版,无法解决 俩字名字 如:肖真 或者带有重复名字如:肖真真
SQL> SELECT TRANSLATE('王海波',SUBSTR('王海波', 1, LENGTH('王海波') - 2),RPAD('*', LENGTH('王海波'), '*')) FNAME FROM DUAL;
FNAME
-----
*海波
SQL> --随机取数解决不了名字重复的问题,如:肖真真
WITH X AS
(SELECT '王海波' NAME
FROM DUAL
UNION ALL
SELECT '肖真' NAME
FROM DUAL
UNION ALL
SELECT '肖真真' NAME
FROM DUAL)
SELECT NAME,
TRANSLATE(NAME,
SUBSTR(NAME,
1,
ROUND(DBMS_RANDOM.VALUE(1, LENGTH(NAME) - 1))),
RPAD('*', LENGTH(NAME), '*')) FNAME
FROM X
NAME FNAME
------ ------------
王海波 *海波
肖真 *真
肖真真 *真真
--只去掉姓,名字超过4个字只留后俩字。
WITH X AS (
SELECT '王海波' NAME FROM DUAL UNION ALL
SELECT '肖真' NAME FROM DUAL UNION ALL
SELECT '肖真真' NAME FROM DUAL UNION ALL
SELECT '阿诺斯瓦辛格' NAME FROM DUAL UNION ALL
SELECT '成吉思汗' NAME FROM DUAL
)
SELECT NAME,
TRANSLATE(NAME,
SUBSTR(NAME,
1,
CASE
WHEN LENGTH(NAME) <= 2 THEN
LENGTH(NAME) - 1
ELSE
LENGTH(NAME) - 2
END),
RPAD('*', LENGTH(NAME), '*')) AS FNAME
FROM X;
NAME FNAME
------------ ------------------------
王海波 *海波
肖真 *真
肖真真 *真真
阿诺斯瓦辛格 ****辛格
成吉思汗 **思汗
这里级联学习一下几个函数:
1.TRANSLATE(EXPR,FROM,TO)
当 FROM = TO 一对一个换
当 FROM < TO 一对一个换
当 FROM > TO 一对一个换,多余补成空
汉字/字符/数字/符号标点等都占一个位置(记忆的话只需要记住FROM > TO这种特殊情况补成空就行)
官方文档:
The following statement translates a license number. All letters 'ABC...Z' are translated to 'X' and all digits '012 . . . 9' are translated to '9':
SELECT TRANSLATE('2KRW229',
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'9999999999XXXXXXXXXXXXXXXXXXXXXXXXXX') "License"
FROM DUAL;
License
--------
9XXX999
The following statement returns a license number with the characters removed and the digits remaining:
SELECT TRANSLATE('2KRW229',
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', '0123456789')
"Translate example"
FROM DUAL;
Translate example
-----------------
2229
如下例子方便理解:
SQL> SELECT TRANSLATE('ABCDEFGHIJ','ABCDEF','123456') FROM DUAL;
TRANSLATE(
----------
123456GHIJ
SQL> SELECT TRANSLATE('ABCDEFGHIJ','ABC','123456') FROM DUAL;
TRANSLATE(
----------
123DEFGHIJ
SQL> SELECT TRANSLATE('ABCDEGHIJ+ABCDEFGHIJ','ABCDEFGHIJ','123456') FROM DUAL;
TRANSLATE('A
------------
12345+123456
SQL> SELECT TRANSLATE('ABCDEGHIJ+ABCDEFGHIJ','ABcdEFGHIJ','123456') FROM DUAL;
TRANSLATE('A
------------
12CD5+12CD56
SQL> SELECT TRANSLATE('我在北京', '北京', 'BeiJing') FROM DUAL;
TRANSL
------
我在Be
SQL> SELECT TRANSLATE('我是小八', '小八', '⑧') FROM DUAL;
TRANS
-----
我是⑧
当然大神们【敬礼】开发出了TRANSLATE函数的几个妙用:
SQL> --取出字符串里的数字:
SQL> SELECT TRANSLATE('23456中国3-00=.,45','0123456789'||'23456中国3-00=.,45','0123456789') FROM DUAL;
TRANSLATE(
----------
2345630045
SQL> --取出字符串里某个符号
SQL> SELECT TRANSLATE('23456中国3-00=.,45','.'||'23456中国3-00=.,45','.') FROM DUAL;
T
-
.
SQL> --取出汉字
SQL> SELECT TRANSLATE('23456中国3-00=.,45','中国'||'23456中国3-00=.,45','中国') FROM DUAL;
TRAN
----
中国
SQL> --当然用这个取出汉字就很牵强,一般就不考虑这个函数了,可以用正则
SQL> SELECT REGEXP_REPLACE('23456中国3-00=.,45','[' || CHR(1) || '-' || CHR(127) || ']') FROM DUAL;
REGE
----
中国
SQL> --字符代码相关的字符对应关系如下
SQL> WITH X AS (SELECT LEVEL AS SEQ FROM DUAL CONNECT BY LEVEL<=132) SELECT SEQ,CHR(SEQ) FROM X;
这个例子里面牵扯到另外一个函数:RPAD(LPAD) 当然这个函数就相对简单:
RPAD/LPAD 函数从右边/左边对字符串使用指定的字符进行填充
RPAD/LPAD(STRING,PADDED_LENGTH,[PAD_STRING])
STRING 表示:被填充的字符串
PADDED_LENGTH 表示:字符的长度,是返回的字符串的数量,如果这个数量比原字符串的长度要短,RPAD/LPAD 函数将会把字符串截取成从左到右的N个字符;
PAD_STRING 是个可选参数,这个字符串是要粘贴到STRING的右边/左边,如果这个参数未写,RPAD函数将会在STRING的右边/左边粘贴【空格】。
SQL> SELECT RPAD('ABCD',1) AS RESULT FROM DUAL;
R
-
A
SQL> SELECT RPAD('ABCD',6) AS RESULT FROM DUAL;
RESULT
------
ABCD
SQL> SELECT RPAD('ABCD',6,'+') AS RESULT FROM DUAL;
RESULT
------
ABCD++
SQL> SELECT LPAD('ABCD',1) AS RESULT FROM DUAL;
R
-
A
SQL> SELECT LPAD('ABCD',6) AS RESULT FROM DUAL;
RESULT
------
ABCD
SQL> SELECT LPAD('ABCD',6,'+') AS RESULT FROM DUAL;
RESULT
------
++ABCD