【问题标题】:Number and date format : altering NLS_SESSION_PARAMETER does not work?数字和日期格式:更改 NLS_SESSION_PARAMETERS 不起作用?
【发布时间】:2012-06-23 14:00:58
【问题描述】:

Oracle 11.2.0.3.0、APEX 4.1.1.00.23。

我们需要在应用中显示数字,格式为FM999999999990.000日期,格式为英文DD-MON-YYYY

即使应用程序语言要改变(法语、西班牙等),我们总是需要这种格式的数字(组分隔符没有空格或逗号,小数分隔符用点,即。- 1254.010)和日期(英文月份名称的三个首字母即 12-FEB-2012)。

这是我们正在使用的全球化属性Application Builder -> Application -> Edit Globalization Attributes):

  • 应用程序主要语言:法语(法国)(fr)
  • 应用程序语言派生自:会话
  • 申请日期格式:DD-MON-YYYY

我无法让它按预期工作...... 我仍然得到像-1254,01 这样的数字和像12-FÉVR.-2012 这样的日期,而不是-1254.01012-FEB-2012。 似乎 APEX 忽略了任何更改会话的调用...

我尝试在“初始化 PL/SQL 代码”属性(Application Builder -> Application -> Edit Security Attributes)中输入以下代码,但没有任何成功:

BEGIN
   EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS= ''.,'' ';
   EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_LANGUAGE = ''AMERICAN'' ';
   EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_LANGUAGE = ''AMERICAN'' ';
END;

我有一个包含以下查询的报告,以查看参数是否正在更改:

SELECT
  a1.parameter as "Parameter",
  a1.value as "Database value",
  a2.value as "Instance value",
  a3.value as "Session value"
FROM
  nls_database_parameters a1
  LEFT JOIN nls_instance_parameters a2 ON a1.parameter = a2.parameter
  LEFT JOIN nls_session_parameters a3 ON a1.parameter = a3.parameter
ORDER BY
  a1.parameter asc;

结果:

如您所见,ALTER SESSION 调用不会改变任何东西...

当我在“Before Header”应用程序进程中尝试ALTER SESSION 调用时,会话似乎已更改(报告显示修改后的值),但我的报告中仍然出现错误的日期和数字格式和物品... 我已经尝试过“Number Field”项目的“Format Mask”属性,但它似乎也没有改变任何东西......

我可以让它工作的唯一方法是在我从 APEX 调用的每个 PL/SQL 函数中调用 ALTER SESSION。对于报告,我可以使用“数字/日期格式”列属性。

问题:有什么方法可以更改整个应用程序的会话的数字和日期参数?


编辑:

当我在每个页面上运行以下 Before Header 进程时:

BEGIN
   APEX_UTIL.SET_SESSION_LANG('fr');
   EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS= ''.,'' ';
   EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_LANGUAGE = ''AMERICAN'' ';
END;

报告显示会话已更改:

然后我创建了一个新的测试页面:

  1. 上述Before Header流程。
  2. 显示 NLS 参数值的报告。
  3. 一份显示我的一张表格中的日期和数字的报告。
  4. 源类型为“SQL 查询”的文本字段项以获取日期。
  5. 源类型为“SQL 查询”的数字字段项以获取数字。
  6. 一个与 JQuery 绑定的按钮,它调用一个应用程序进程,该进程调用一个 PL/SQL 过程,htp.prn() 来自表的日期,然后填充我的文本字段项。
  7. 一个与 JQuery 绑定的按钮,用于插入(使用应用程序进程等)表中的两个字段。

加载页面后,报告显示会话已正确更改,并且我在项目和报告中获得了正确的数字和日期格式。 “插入”按钮可以毫无问题地进行插入。

当我单击“getDate”按钮以使用 ajax 调用从数据库中获取日期时,我得到的是法语格式的日期!然后“插入”按钮失败(invalid date)。

您知道为什么从 JavaScript 获取值(对调用包中的 PL/SQL 函数的按需应用程序进程进行 ajax 调用)会导致问题吗?

这仍然很奇怪,就像在我的其他现有页面中一样,即使我使用相同的 Before Header 流程​​,我在报告中的格式也会出错。我们必须和我的同事一起进一步研究这个问题,也许我们在某个地方有一段“隐藏”的代码会破坏一切。

我查看了页面的调试消息数据,但对我来说没有什么奇怪的。

【问题讨论】:

  • 您能否在 apex.oracle.com 上尝试一下,看看它的反应如何?我也会尝试在我的环境中试一试。
  • 今天没时间,下周初可以试一试。谢谢。
  • 很抱歉这么久才回复你:我只用 nls_numeric_characters 试过这个,我似乎没有遇到任何问题。您的架构数据库用户是否有权更改?如果你从 sql 开发者那里运行 alter session,它会起作用吗?
  • 这是一篇包含大量信息的好帖子,我希望我能提供更多帮助。也许尝试再次在 OTN 上发布您的帖子?我确实认为 ajax 检索是因为它是另一个使用它的会话。我实际上并没有期望您使用 alter session 的前标头进程也可以进行页面处理,但是我需要阅读 apex + db 会话管理才能真正了解它是如何工作的。你的应用程序属性>安全设置对你不起作用,这对我来说很好。
  • 正如 fac586 在 OTN 上告诉我的那样,实际上应用了安全设置但立即被会话语言设置取代,这是我认为的主要问题。一种解决方案是从应用程序项 FSP_LANGUAGE_PREFERENCE 而不是 Session 派生应用程序语言。我已经测试过,一切正常。但是我确信有一个解决方案,同时保留从会话派生的应用程序语言。我会继续调查:)

标签: session oracle-apex number-formatting date-formatting nls


【解决方案1】:

很抱歉,我不能告诉你为什么全球化属性没有“坚持”跨语言,因为我很幸运不必担心它。您是否尝试过在此处使用替换变量而不是将文字放入?它不应该解决这个问题,但值得一试,嗯?我尝试了一下,设置应用程序项的值:= SYSDATE。当我更改应用程序->全局设置->应用程序日期格式时,每次我重新显示页面项目所在的页面时,它都会应用指定的格式。

另外,我很难想象您的用户有权更改 APEX_PUBLIC_USER 架构的会话,这是运行您的应用程序的地方。也就是说,我很难想象 DBA 会授予该权限,因为这对那个帐户来说似乎很危险。

另外,请记住 Apex 会话(如 URL 中的会话 ID 所示)与 Oracle 会话不同。因此,您上面的匿名块实际上可能能够更改它在上面提到的测试页面运行的 Oracle 会话中的会话,但是您与数据库的 AJAX 调用会话将在不同的 Oracle 会话中运行。所以“ALTER SESSION”对它没有影响。

希望本次讨论能帮助您找到答案。如果有,请给我道具! :-)

【讨论】:

    【解决方案2】:

    我不知道它是否回答了你的问题,但这个链接刚刚拯救了我的一天:

    就我而言,我有一个法国环境,我需要一个“美国 Oracle 数据库”(本地化)。每次我为sqlldr 创建会话时,我都有一个法语 NLS(尽管我需要一个美国 NLS)。

    这是此页面的副本,以防它消失:



    按照此过程为 Oracle 数据库设置 NLS_LANG 环境变量。

    要为 Oracle 数据库设置 NLS_LANG 环境变量,我们必须确定 NLS_LANG 的值。

    运行命令:

    SELECT * FROM V$NLS_PARAMETERS
    

    记下 NLS_LANG 值,格式为 [NLS_LANGUAGE]_[NLS_TERRITORY].[NLS_CHARACTERSET]

    例如:American_America.UTF8

    对于 Windows:

    • 导航到Control Panel > System 并单击Advanced tab。点击Environment Variables
    • System variables 部分,单击New
    • 在变量名称字段中,输入NLS_LANG
    • 在变量值字段中,输入在步骤 1 中返回的 NLS_LANG 值(例如:American_America.UTF8)。

    对于 UNIX,如下所示设置变量:

    setenv NLS_LANG <NLS_LANG>
    

    例如:

    setenv NLS_LANG American_America.UTF8.
    

    如果您的数据是 7 位或 8 位 ASCII 并且 Informatica Server 在 UNIX 上运行,则设置

    NLS_LANG <NLS_LANGUAGE>_<NLS_TERRITORY>.WE8ISO8859P1
    

    注意:确保按照此过程所述正确设置 NLS_LANG 变量,否则您的数据将无法正确显示。

    创建变量后重启机器。

    【讨论】:

      【解决方案3】:

      您是否在 Apex 应用程序中使用它?如果是这样,那么应用程序创建过程的一部分是指定 NLS 相关值。 Apex 将始终使用应用程序设置覆盖您的设置。

      我总是使用固定的 NLS 值创建应用程序,因此我确信日期和数字会正确显示。

      您可以拥有 Apex 切换 NLS 设置(应用程序首选项、项目首选项)。这些工作都很好。

      但您需要在应用程序级别而不是数据库级别进行。

      【讨论】:

        【解决方案4】:

        从 apex-client 到服务器的每个调用都是单独的 oracle 会话。 它回答了为什么你会通过 js 回调得到错误的格式。

        你试过了吗?

        Application Express 会话语言可以通过 APEX_UTIL.SET_SESSION_LANG 过程或通过 URL 中 F 过程的 P_LANG 参数设置。

        您也可以尝试将初始化代码放在这里:安全属性 -> 数据库会话 -> 初始化 PL/SQL 代码。但我不确定回调。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-01-03
          • 2018-12-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多