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

标签 java oracle arabic oracle12c

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

我的阿拉伯字符返回这样的“????”

enter image description here

即使在 java 上,当我获取数据时它也不会返回阿拉伯值

{
   "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 developer 时,我可以 SELECT , INSERT阿拉伯值(value)观

enter image description here

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

  • Windows 10 笔记本电脑(使用 windows 10 管理员用户登录)
  • Oracle 12c(以系统用户登录)
  • Java 版本“1.8.0_152”

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

但不幸的是我不能在sqlplus上使用这个命令

SHUTDOWN IMMEDIATE

它返回这个错误信息

ORA-01031: insufficient privileges

我在上找到了这个答案 https://itkbs.wordpress.com/2016/02/05/solving-ora-01031-insufficient-privileges-while-connecting-as-sqlplus-as-sysdba/

但不幸的是我没有“本地用户和组”部分我认为它只在 Windows NT 或服务器上

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

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

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

enter image description here

在 sql plus 上我得到这个错误: enter image description here

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

但它一直给我同样的问题

所以我将我创建的注册表项 “NLS_LANG” 重命名为不同的名称,这是我唯一真正更改的内容,以恢复所有内容 并且数据库再次运行

enter image description here

所以我的问题是:

  • 如何 InsertSelect阿拉伯语值中的数据? (不知道是Oracle还是Java还是SQLPLUS哪里有问题!)

更新 1:我的 Java 代码:

  • ** OracleDBConnect2 类:**

    包 com.oracle.testconnect;

    导入java.io.BufferedReader; 导入java.io.文件; 导入 java.io.FileOutputStream; 导入 java.io.InputStreamReader; 导入 java.io.PrintWriter; 导入 java.sql.Connection; 导入 java.sql.DriverManager; 导入 java.sql.ResultSet; 导入 java.sql.Statement; 导入 java.text.SimpleDateFormat; 导入 java.util.ArrayList; 导入 java.util.Calendar; 导入java.util.Date; 导入 java.util.HashMap; 导入 java.util.Map;

    导入 org.json.JSONArray; 导入 org.json.JSONObject;

    公共(public)类 OracleDBConnect2 { static PrintWriter logPrintWriter;

    public static void main(String args[]) {
        System.setProperty("file.encoding", "UTF-8");
    
        JSONObject jsonObj = new JSONObject();
        JSONArray jsonArray = new JSONArray();      // getting current datetime
    
        try {
            // create the connection object
            Connection dbConnection = DriverManager
                    .getConnection(
                            "jdbc:oracle:thin:@url:port:DBName",
                            "username", "password");
    
            // create the statement object
            Statement sqlStatement = dbConnection.createStatement();
    
            // execute query
            String query = "select * from employee";
            ResultSet results = sqlStatement.executeQuery(query);
    
            // Convert result to json array
            jsonArray = Convertor.convertToJSON(results);
            System.out.println("jsonArray " + jsonArray.toString());
    
    
            // Add JSON Array results to employee JSON Object
            jsonObj.put("employees", jsonArray);
    
    
            // 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);
            if (!file.exists()) {
                file.mkdirs();
                file.createNewFile();
            }
    
            // Writing the user input to the file
            printWriter.write(jsonObj.toString());
            printWriter.flush();
            fileOutputStream.close();
            printWriter.close();
    
            // close the connection object
            dbConnection.close();
    
        } catch (Exception e) {
            System.out.println(e);
        }
    
    }
    

  • ** 转换器类:**

    公共(public)类转换器{

    public static JSONArray convertToJSON(ResultSet resultSet) throws Exception {
        JSONArray jsonArray = new JSONArray();
        while (resultSet.next()) {
            int total_rows = resultSet.getMetaData().getColumnCount();
            JSONObject obj = new JSONObject();
            for (int i = 0; i < total_rows; i++) {
                obj.put(resultSet.getMetaData().getColumnLabel(i + 1).toLowerCase(), resultSet.getObject(i + 1));
            }
            jsonArray.put(obj);
            System.out.println(resultSet.getString(1));
        }
        return jsonArray;
    }
    

更新二:修改cmd的代码页

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

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

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

检查这是一个截图:

enter image description here

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'              ''$'\330\271\330\261\330\250\331\212'

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'              ''$'\330\271\330\261\330\250\331\212'

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>

最佳答案

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

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

SQLplus 从命令行继承编码。如果您使用 chcp 28596,这意味着 ISO 8859-6(参见 Code Page Identifiers),那么您的 NLS_LANG 值中的字符集必须是 .AR8ISO8859P6(参见 Character Sets)

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

或者,如果您更喜欢使用 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

同时检查这个答案:OdbcConnection returning Chinese Characters as "?"

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

关于java - 在 Oracle 12c 上插入/检索阿拉伯语数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47950996/

相关文章:

java - 来自子对象字段聚合的自定义 Hibernate POJO 字段

sql - Oracle 11 中的递归 SQL 选择查询

php - 插入阿拉伯语文本 MySQL

java - 使用插入排序只对数组的一部分进行排序

java - 当我切换到另一个包含回收器 View 的 Activity 时,应用程序崩溃

sql - 在循环中重试死锁,他们最终会解决吗?

android - 自定义字体字符分开?

html - 强制阿拉伯字符遵循从左到右的顺序

Java 库 : Command Line Option Parser

database - 如何在 oracle 表上强制执行唯一的 2 元组?