1

我对某些代码有问题,根本原因是会话级别的 NLS_NUMERIC_CHARACTERS 设置。

当我直接在数据库上运行查询时:

SQL> select 'nls_database_parameters' , p.* from nls_database_parameters p where PARAMETER = 'NLS_NUMERIC_CHARACTERS'
  2  union all
  3  select 'nls_session_parameters', p.* from nls_session_parameters p where PARAMETER = 'NLS_NUMERIC_CHARACTERS'
  4  union all
  5  select 'nls_instance_parameters', p.* from nls_instance_parameters p where PARAMETER = 'NLS_NUMERIC_CHARACTERS';
'NLS_DATABASE_PARAMETERS' PARAMETER                VALUE
------------------------- ------------------------ -----
nls_database_parameters   NLS_NUMERIC_CHARACTERS   .,
nls_session_parameters    NLS_NUMERIC_CHARACTERS   .,
nls_instance_parameters   NLS_NUMERIC_CHARACTERS   .,

但是,当我从 weblogic 数据源运行相同的查询时

select 'nls_database_parameters' , p.* from nls_database_parameters p where PARAMETER = 'NLS_NUMERIC_CHARACTERS'
union all
select 'nls_session_parameters', p.* from nls_session_parameters p where PARAMETER = 'NLS_NUMERIC_CHARACTERS'
union all
select 'nls_instance_parameters', p.* from nls_instance_parameters p where PARAMETER = 'NLS_NUMERIC_CHARACTERS';

--  'NLS_DATABASE_PARAMETERS',  PARAMETER,  VALUE
1   nls_database_parameters NLS_NUMERIC_CHARACTERS  .,
2   nls_session_parameters  NLS_NUMERIC_CHARACTERS  , 
3   nls_instance_parameters NLS_NUMERIC_CHARACTERS  .,

会话值错误并且在通过 weblogic 数据源访问时被某些触发器/脚本重置,我检查了 weblogic 启动脚本等,看看我们是否在某处重置但没有帮助。

如果有人遇到类似问题,我们将不胜感激在这个方向上的任何指示/想法。

4

2 回答 2

3

这不太可能被明确设置。我敢打赌,它是由于用于初始化 JVM的user.language和值而被隐式设置的。user.country我不知道 WebLogic 默认是如何获取这些的,但我猜服务器的语言环境设置为逗号是小数点分隔符的地方。

您应该能够通过在 startWebLogic 脚本中设置语言和国家/地区来覆盖默认的 WebLogic 设置

set JAVA_OPTIONS=%JAVA_OPTIONS% -Duser.language=en -Duser.country=US

当然,这也可能会影响其他事情(例如错误消息的语言)。

于 2016-01-26T23:43:40.040 回答
3

我不熟悉 Weblogic 方面的事情,但是您可以通过在 DBA_SOURCE 中搜索其源代码对象(触发器、过程、包、函数)从 Oracle 中获取材料。它可能包含类似于以下内容的“立即执行”语句(或等效的 DBMS_SQL 动态 SQL 调用):

alter session set nls_numeric_characters = ',.';

或者它也可以调用 DBMS_SESSION.SET_NLS 过程:

dbms_session.set_nls('NLS_NUMERIC_CHARACTERS', '".,"');

如下查询它应该指向一些嫌疑人(也可能是一些误报)。您可以通过按所有者过滤来改进它。

SELECT *
  FROM dba_source s
 WHERE (upper(s.text) LIKE '%SET\_NLS%' ESCAPE '\'
        OR upper(s.text) LIKE '%NLS\_NUMERIC\_CHARACTERS%' ESCAPE '\')
       AND owner != 'SYS';

如果动态视图 V$SQL 是匿名的 PL/SQL 块或脚本,那么它可能会有您的命令。

SELECT *
 FROM v$sql s
WHERE (upper(s.sql_fulltext) LIKE '%SET\_NLS%' ESCAPE '\'
       OR upper(s.sql_fulltext) LIKE '%NLS\_NUMERIC\_CHARACTERS%' ESCAPE '\')
      AND s.parsing_schema_name = 'YOUR_DB_USER';

如果您已经发现导致错误的代码并且它处于控制之下,您还可以通过使用以下语法在 to_number(或 to_char)中显式执行转换来修复转换:

SQL> select to_number('1.5', '999999D999', 'NLS_NUMERIC_CHARACTERS=,.'),
  2         to_number('1.5', '999999D999', 'NLS_NUMERIC_CHARACTERS=.,')
  3    from dual;
TO_NUMBER('1.5','999999D999',' TO_NUMBER('1.5','999999D999','
------------------------------ ------------------------------
                            15                            1,5

这样您就可以对它免疫 nls 会话,但是修复所有代码以使用它可能是不可行的。

于 2016-01-26T22:01:04.980 回答