Java 多语言查询中的正则表达式不适用于应用程序,但适用于SQL开发人员和单元测试
对于包含正则表达式的以下查询,我有一个奇怪的行为:Java 多语言查询中的正则表达式不适用于应用程序,但适用于SQL开发人员和单元测试,java,sql,regex,oracle,multilingual,Java,Sql,Regex,Oracle,Multilingual,对于包含正则表达式的以下查询,我有一个奇怪的行为: SELECT COALESCE(lang.TITLE, ids.message_id) AS TEXT, ids.message_id FROM (SELECT CASE WHEN regexp_instr(messages.NR, '[a-z]{2}[[:space:],_-]\d+[-_]\d{2,6}') > 0 THEN regexp_substr(messages.NR, '\d+')
SELECT COALESCE(lang.TITLE, ids.message_id) AS TEXT,
ids.message_id
FROM
(SELECT
CASE
WHEN regexp_instr(messages.NR, '[a-z]{2}[[:space:],_-]\d+[-_]\d{2,6}') > 0
THEN regexp_substr(messages.NR, '\d+')
ELSE messages.NR
END AS message_id
FROM
( SELECT 'GB 28647854-04' AS NR FROM dual
UNION
SELECT 'GB 5310031-05' AS NR FROM dual
UNION
SELECT '9184' AS NR FROM dual
) messages
) ids,
LOCAL_TITLES lang
WHERE ids.message_id = '' || lang.NUMBER_NO(+);
LOCAL\u标题
包含以下条目:
- 5310031 |一些本地化文本
- 9184 |另一个文本
- 28647854 | 28647854
- 一些本地化文本| 5310031
- 另一个文本| 9184
- GB 28647854-04 | GB 28647854-04
- GB 5310031-05 | GB 5310031-05
- 另一个文本| 9184
当正则表达式来自web应用程序时,您知道为什么它的行为会不同吗?您的正则表达式正在寻找具有
[a-z]
模式的小写字符。您的双生成数据具有大写GB,因此它们与默认区分大小写的设置不匹配,至少在我的语言环境中是这样的:
alter session set nls_sort = 'BINARY';
SELECT
CASE
WHEN regexp_instr(messages.NR, '[a-z]{2}[[:space:],_-]\d+[-_]\d{2,6}') > 0
THEN regexp_substr(messages.NR, '\d+')
ELSE messages.NR
END AS message_id
FROM
( SELECT 'GB 28647854-04' AS NR FROM dual
UNION
SELECT 'GB 5310031-05' AS NR FROM dual
UNION
SELECT '9184' AS NR FROM dual
) messages;
MESSAGE_ID
--------------
9184
GB 28647854-04
GB 5310031-05
如果将会话设置为不区分大小写,则会执行以下操作:
alter session set nls_sort = 'BINARY_CI';
SELECT
CASE
WHEN regexp_instr(messages.NR, '[a-z]{2}[[:space:],_-]\d+[-_]\d{2,6}') > 0
THEN regexp_substr(messages.NR, '\d+')
ELSE messages.NR
END AS message_id
FROM
( SELECT 'GB 28647854-04' AS NR FROM dual
UNION
SELECT 'GB 5310031-05' AS NR FROM dual
UNION
SELECT '9184' AS NR FROM dual
) messages;
MESSAGE_ID
--------------
9184
28647854
5310031
您还可以在每个正则表达式调用中使其不区分大小写:
SELECT
CASE
WHEN regexp_instr(messages.NR, '[a-z]{2}[[:space:],_-]\d+[-_]\d{2,6}', 1, 1, 0, 'i') > 0
THEN regexp_substr(messages.NR, '\d+', 1, 1, 'i')
ELSE messages.NR
END AS message_id
...
或者只展开角色类:
WHEN regexp_instr(messages.NR, '[a-zA-Z]{2}[[:space:],_-]\d+[-_]\d{2,6}') > 0
或
您的某些会话是使用二进制\u CI(或其他一些不区分大小写的)设置创建的,但您的“web应用程序”设置不是。这可能取决于每个应用程序所使用的区域设置,因此更改应用程序区域设置也可以修复差异;但让模式更符合逻辑可能更好
更具体地说,在您的情况下(查看了您的个人资料),如果您的地区是德国,那么您的NLS_排序为be DERMAN,其行为与BINARY_CI对我在英国地区的行为相同。大概您的SQL开发人员和单元测试是使用德国设置运行的,而您的web应用程序不是,这是因为它自己的默认设置或设计
.您的web应用程序不使用DAO访问数据吗?因为DAO似乎可以工作(至少您的测试似乎表明了这一点),所以应该可以。因此,您要么以其他方式执行该查询/表达式,要么您的测试以某种方式具有不同的设置。在任何情况下,我们都可能需要更多信息。对于
java.sql.Connection
实现,设置确实有点不同:web应用程序使用PooledConnection
,而在测试运行期间,我们调用DriverManager.getConnection()
。除此之外,在实现上没有区别。web应用程序在Weblogic 12c服务器上运行。请注意,这可能不仅在实现上存在差异,而且在配置、库(例如,不同的JDBC驱动程序)等方面也存在差异。
WHEN regexp_instr(messages.NR, '[[:alpha:]]{2}[[:space:],_-]\d+[-_]\d{2,6}') > 0