我在Oracle中发现了一个奇怪的情况
面临的情况
我创建了一个带有 substr 的函数,用于替换长度字节 >= 2 的所有字符。
我使用substr将字符一一分割,如果长度>=2的字节则用空格替换。
它在我的会话中成功运行,但在 Oracle 作业中不起作用。 我发现有可能替换更多的字符,例如 奥阿兹德 它将带着价值返回 一个SD
为了我的进一步测试,我认为这是因为 NLS 设置
在 German.Germany.AL32UTF8 中,substr 函数无法获取正确的字符,尤其是在德语特殊字符之后。然而它在用户会话中工作
除此之外,我还尝试过使用 regex_replace 但它也不适用于 Oracle 作业,无法替换它。
字符串:= REGEXP_REPLACE(ps_string, '[äöüßäÖÜ]', ' ');
除了更改 NLS 设置之外,还有其他解决方案吗?
您的问题是不同数据库中的字符集不同。
在我的数据库中,NLS Settings = 'AMERICAN.AMERICA.AL32UTF8'
WITH CTE AS (SELECT 'Aöasd' STR FROM DUAL)
SELECT SUBSTR(STR,LEVEL,1) AS NEW_ST,
LENGTHB(SUBSTR(STR,LEVEL,1)) AS NEW_ST_LB
FROM CTE
CONNECT BY LEVEL <= LENGTH(STR);
N NEW_ST_LB
- ----------
A 1
ö 2
a 1
s 1
d 1
现在,我在另一个具有德语字符集的数据库中尝试了相同的查询,所有字符的结果都是 1。 (
WE8ISO8859P15
)
N NEW_ST_LB
- ----------
A 1
ö 1 --<--- See this
a 1
s 1
d 1
这个东西是
WE8ISO8859P15
字符集,只需要1个字节来存储它,而不是2个字节。
使用
CONVERT
函数将每个字符转换为 UTF8
,然后检查字符的字节长度,如果大于 1,则进行替换。
查询:
WITH CTE AS (SELECT 'Aöasd' STR FROM DUAL)
SELECT CONVERT(SUBSTR(STR,LEVEL,1), 'UTF8' ) AS NEW_ST,
LENGTHB( CONVERT(SUBSTR(STR,LEVEL,1), 'UTF8' )) AS NEW_ST_LB
FROM CTE
CONNECT BY LEVEL <= LENGTH(STR);
数据库中的结果为 NLS 设置 = 'AMERICAN.AMERICA.AL32UTF8'
NEW_ST NEW_ST_LB
-------------------- ----------
A 1
ö 2
a 1
s 1
d 1
数据库中的结果为 NLS 设置 = 'German.Germany.AL32UTF8'
NEW_S NEW_ST_LB
----- ----------
A 1
ö 2
a 1
s 1
d 1