如何让基于REGEXP_REPLACE的驼峰转下划线函数不依赖NLS参数?
解决camelCase转snake_case函数依赖NLS_LANG的问题
问题根源
你原函数里的正则表达式使用[A-Z]/[a-z]字符类,搭配'c'(区分大小写)参数,但Oracle的正则字符类匹配规则依赖数据库的NLS_SORT和NLS_LANGUAGE设置。在非美式环境(比如西里尔语环境)中,这些字符类的匹配范围会偏离ASCII英文字母区间,导致原本的小写字母被错误识别为非[a-z]范围,进而被过度拆分。
修改方案
改用ASCII码范围精准匹配英文字母,彻底摆脱NLS设置的影响。直接在正则中指定十六进制的ASCII区间:
- 大写A-Z对应十六进制
\x41-\x5A(十进制65-90) - 小写a-z对应十六进制
\x61-\x7A(十进制97-122)
同时去掉'c'参数,因为固定ASCII范围的匹配不需要依赖NLS的大小写规则。
修改后的函数代码
create function camel_to_snake(str varchar2) return varchar2 as begin return lower( regexp_replace( regexp_replace ( str, '([\x41-\x5A])([\x41-\x5A][\x61-\x7A])', '\1_\2', 1, 0 ), '([\x61-\x7A])([\x41-\x5A])', '\1_\2', 1, 0 ) ); end; /
效果验证
无论客户端NLS_LANG设置为美式还是其他语言环境,执行测试查询都会得到正确结果:
select column_value as camel_case, camel_to_snake(column_value) as snake_case from table(t_varchar_table( 'Foo', 'FooBar', 'foobar' ));
输出:
CAMEL_CASE SNAKE_CASE ---------------------------------------- ---------------------------------------- Foo foo FooBar foo_bar foobar foobar
内容的提问来源于stack exchange,提问作者DZN
相关产品推荐
相关产品推荐

