在 Oracle 12c 上插入/检索阿拉伯语数据

insert / retrieve Arabic data on Oracle 12c

我在从 Oracle Database 12c 获取阿拉伯语内容时遇到问题,我已经关注了大多数已回答的问题,但没有任何效果。

我的阿拉伯语字符 returns 像这样 "????"

即使在 java 上,当我获取数据时它也没有 returns 阿拉伯语值

{
   "employees":[
      {
         "fname":"????",
         "lname":"Saleh",
         "amount":30000,
         "phone":"96600000097"
      },
      {
         "fname":"Saleh",
         "lname":"Salem",
         "amount":40000,
         "phone":"96600000097"
      },
      {
         "fname":"Hasan",
         "lname":"Damis",
         "amount":25000,
         "phone":"96600000097"
      },
      {
         "fname":"Ahmad",
         "lname":"?????",
         "amount":25000,
         "phone":"96600000097"
      },
      {
         "fname":"Abbas",
         "lname":"Motwali",
         "amount":20000,
         "phone":"96600000097"
      }
   ]
}

而当我使用 sql 开发人员时,我可以 SELECT , INSERT 阿拉伯值

我在笔记本电脑上使用 oracle 进行学习:

我在这里和互联网上发现了很多问题,例如:

但不幸的是我不能在 sqlplus

上使用这个命令
SHUTDOWN IMMEDIATE

它returns这个错误信息

ORA-01031: insufficient privileges

我在 https://itkbs.wordpress.com/2016/02/05/solving-ora-01031-insufficient-privileges-while-connecting-as-sqlplus-as-sysdba/

但不幸的是我没有 "local users and groups" 部分我认为它只在 windows NT 或服务器

还有一个 Internet 上的答案建议在系统注册表中添加 "NLS_LANG" 并为 Arabic Unicode 分配值 AR8MSWIN1256(实际上有不同的值)

不幸的是我遇到了另一个问题

ORA-12505, TNS:listener does not currently know of SID given in connect descriptor

和 sql 加上我得到这个错误:

我遵循了这个答案,但它没有连接到我的数据库

但它一直给我同样的问题

所以我将我创建的注册表项 "NLS_LANG" 重命名为不同的名称,这是我唯一真正改变的东西,以恢复一切 并且数据库再次 运行

所以我的问题是:

更新一:我的Java代码:

更新 2:更改 cmd 上的代码页

正如@plirkee 和@Vahadin 所建议的 我已将 CMD 上的代码页更改为阿拉伯代码 我还创建了一个名为“عربي”的空白文件,当我测试 ls 命令时它显示这样的名称 ''$'01010012'

而当我在 sqlplus 上尝试 select 语句时,我得到的阿拉伯值是 ????

我知道 cmd 可能不支持阿拉伯语,但 oracle 的结果(如果配置没有问题)不应显示为 ????而应该将其显示为我在 cmd

中创建的文件名

检查这是截图:

C:\Users\ahmed\Documents>chcp 20420
Active code page: 20420

C:\Users\ahmed\Documents>ls
'Custom Office Templates'  'My Videos'
 FeedbackHub                desktop.ini
'HP ePrint'                 hp.applications.package.appdata
'My Music'                  hp.system.package.metadata
'My Pictures'              ''$'01010012'

C:\Users\ahmed\Documents>chcp 28596
Active code page: 28596

C:\Users\ahmed\Documents>ls
'Custom Office Templates'  'My Videos'
 FeedbackHub                desktop.ini
'HP ePrint'                 hp.applications.package.appdata
'My Music'                  hp.system.package.metadata
'My Pictures'              ''$'01010012'

C:\Users\ahmed\Documents>sqlplus

SQL*Plus: Release 12.2.0.1.0 Production on Sat Dec 23 13:33:54 2017

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Enter user-name: system
Enter password:
Last Successful login time: Sat Dec 23 2017 13:27:42 +03:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> select * from employee
  2  ;

FNAME      LNAME      PHONE            AMOUNT
---------- ---------- ------------ ----------
????       Saleh      966000000000      30000
Saleh      Salem      966000000000      40000
Hasan      Damis      966000000000      25000
Ahmad      ?????      966000000000      25000
Abbas      Motwali    966000000000      20000

SQL>

据我所知,您的数据库可以接受阿拉伯语(如您在 sql developer 示例中所示),因此问题出在 javasqlplus(命令行)。

关于命令行,我认为问题出在使用的代码页上。

尝试使用 chcp dos 命令更改代码页。我不懂任何阿拉伯语,但看一看 here 有一些选择。尝试 chcp 720chcp 1256709708(换句话说,您在页面上找到的任何阿拉伯语)然后 运行 sqlplus 命令.也有可能无法在 dos 中显示阿拉伯语(如@Vahadin 的 link 所建议)。

关于 java 我认为您没有提供足够的信息 - 使用的源代码、编码(您使用 utf-8 吗?)等。

希望这对您有所帮助 - 并且不会让您更加困惑..

首先,ALTER DATABASE CHARACTER SET ... 从 Oracle 10g 开始不再支持。你不应该使用它,你可能会破坏你的数据库。遵循 Oracle 的官方指南:Character Set Migration or use the DMU - Database Migration Assistant for Unicode

NLS_LANG 的格式为 "language_territory.charset"。 AR8MSWIN1256 不起作用,使用带点的 .AR8MSWIN1256(每个组件都是可选的,因此您可以跳过语言和地区)

SQLplus 从命令行继承编码。如果您使用 chcp 28596,这意味着 ISO 8859-6(参见 Code Page Identifiers) then character set in your NLS_LANG value must be .AR8ISO8859P6 (see Character Sets

如果你喜欢使用 NLS_LANG=.AR8MSWIN1256 那么你必须 运行 chcp 1256 在启动 sqlplus 之前。

或者,如果您更喜欢使用 UTF-8 运行,可以这样:

c:\> chcp 65001
c:\> set NLS_LANG=.AL32UTF8
c:\> sqlplus ...

注意,环境变量(即 set NLS_LANG=.AL32UTF8)优先于注册表设置。

确保您在 cmd.exe 中使用的字体支持阿拉伯字符。您可以使用此页面进行测试:https://www.fileformat.info/info/unicode/font/fontlist.htm

同时检查这个答案:

关于Java我帮不了你,我不熟悉Java/JDBC。请记住,Java 不使用 NLS_LANG 设置,请参阅 Database JDBC Developer's Guide - Globalization Support

我只想合并和改进@Plirkee 评论提供的附加注释的答案 and @Wernfried Domscheit answer

1.在 CMD 上解决问题:

@Domscheit 先生回答 建议执行以下操作:

c:\> chcp 65001
c:\> set NLS_LANG=.AL32UTF8
c:\> sqlplus ...

如果您不想每次都输入前 2 个命令,您可以通过注册表添加它们:

  • 将代码页设置为 65001:

按照此 link 中的说明进行操作:

  1. 开始 -> 运行 -> regedit
  2. 转到[HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor]
  3. 添加名为:Autorun 的新字符串值
  4. 将值更改为 chcp 65001
  5. 关闭

    • 将 NLS_LANG 设置为 .AL32UTF8

      1. 开始 -> 运行 -> regedit
      2. 转到[HKEY_LOCAL_MACHINE\Software\Oracle\{OracleHome#}]
      3. 添加名为的新字符串值:NLS_LANG
      4. 将值更改为 .AL32UTF8
      5. 关闭

现在当您打开 CMD 时,您会发现 Active code page: 65001 并且您可以直接在 sqlplus 上工作

Microsoft Windows [Version 10.0.15063]
(c) 2017 Microsoft Corporation. All rights reserved.
Active code page: 65001

C:\Users\ahmed>sqlplus

SQL*Plus: Release 12.2.0.1.0 Production on Sat Dec 23 16:10:23 2017

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Enter user-name: system
Enter password:
Last Successful login time: Sat Dec 23 2017 15:58:21 +03:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> select * from employee;

FNAME      LNAME      PHONE            AMOUNT
---------- ---------- ------------ ----------
أ ح م د       Saleh      966000000001      30000
Saleh      Salem      966000000001      40000
ح س ن        Damis      966000000001      25000
Ahmad      Saleh      966000000001      25000
Abbas      Motwali    966000000001      20000

SQL>

2。在 Java 中显示阿拉伯语: @Plirkee 先生评论 建议执行以下操作:

// Getting the output stream of the file for writing
    File file = new File(Constants.JSON_FILE_PATH);
    FileOutputStream fileOutputStream = new FileOutputStream(file);
//  PrintWriter printWriter = new PrintWriter(fileOutputStream);  // old line 
// make sure that the stuff you are writing to the file is utf-8
    PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8)); 

这会将 ????? 字符修复为未知内容,例如 أحمد
要解决此问题,请确保将您的 IDE 编码更改为 UTF-8(假设您使用的是 Eclips):

Window -> 首选项 -> 常规 -> 工作区 -> 文本文件编码

更改为 UTF-8