在 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 进行学习:
- Windows 10 台笔记本电脑(使用 windows 10 管理员用户登录)
- Oracle 12c(以系统用户登录)
- java版本“1.8.0_152”
我在这里和互联网上发现了很多问题,例如:
- Can't insert arabic characters into oracle database
- how to insert Arabic text to oracle database?
- https://dba.stackexchange.com/questions/23692/arabic-characters-not-displaying-in-oracle-database
- https://community.oracle.com/thread/2529426?start=0&tstart=0
但不幸的是我不能在 sqlplus
上使用这个命令
SHUTDOWN IMMEDIATE
它returns这个错误信息
ORA-01031: insufficient privileges
但不幸的是我没有 "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" 重命名为不同的名称,这是我唯一真正改变的东西,以恢复一切
并且数据库再次 运行
所以我的问题是:
- 如何
Insert
和Select
阿拉伯值的数据? (不知道是Oracle还是Java还是SQLPLUS哪里有问题!)
更新一:我的Java代码:
** OracleDBConnect2 Class:**
包 com.oracle.testconnect;
进口java.io.BufferedReader;
导入 java.io.File;
导入 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;
publicclassOracleDBConnect2{
静态 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);
}
}
}
** 转换器 Class:**
public class 转换器 {
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;
}
}
更新 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
示例中所示),因此问题出在 java
和 sqlplus
(命令行)。
关于命令行,我认为问题出在使用的代码页上。
尝试使用 chcp
dos 命令更改代码页。我不懂任何阿拉伯语,但看一看 here 有一些选择。尝试 chcp 720
或 chcp 1256
或 709
或 708
(换句话说,您在页面上找到的任何阿拉伯语)然后 运行 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 中的说明进行操作:
- 开始 -> 运行 -> regedit
- 转到
[HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor]
- 添加名为:Autorun 的新字符串值
- 将值更改为
chcp 65001
关闭
将 NLS_LANG 设置为 .AL32UTF8
- 开始 -> 运行 -> regedit
- 转到
[HKEY_LOCAL_MACHINE\Software\Oracle\{OracleHome#}]
- 添加名为的新字符串值:NLS_LANG
- 将值更改为
.AL32UTF8
- 关闭
现在当您打开 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
我在从 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 进行学习:
- Windows 10 台笔记本电脑(使用 windows 10 管理员用户登录)
- Oracle 12c(以系统用户登录)
- java版本“1.8.0_152”
我在这里和互联网上发现了很多问题,例如:
- Can't insert arabic characters into oracle database
- how to insert Arabic text to oracle database?
- https://dba.stackexchange.com/questions/23692/arabic-characters-not-displaying-in-oracle-database
- https://community.oracle.com/thread/2529426?start=0&tstart=0
但不幸的是我不能在 sqlplus
上使用这个命令SHUTDOWN IMMEDIATE
它returns这个错误信息
ORA-01031: insufficient privileges
但不幸的是我没有 "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" 重命名为不同的名称,这是我唯一真正改变的东西,以恢复一切 并且数据库再次 运行
所以我的问题是:
- 如何
Insert
和Select
阿拉伯值的数据? (不知道是Oracle还是Java还是SQLPLUS哪里有问题!)
更新一:我的Java代码:
** OracleDBConnect2 Class:**
包 com.oracle.testconnect;
进口java.io.BufferedReader; 导入 java.io.File; 导入 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;
publicclassOracleDBConnect2{ 静态 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); } }
}
** 转换器 Class:**
public class 转换器 {
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; }
}
更新 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
示例中所示),因此问题出在 java
和 sqlplus
(命令行)。
关于命令行,我认为问题出在使用的代码页上。
尝试使用 chcp
dos 命令更改代码页。我不懂任何阿拉伯语,但看一看 here 有一些选择。尝试 chcp 720
或 chcp 1256
或 709
或 708
(换句话说,您在页面上找到的任何阿拉伯语)然后 运行 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 评论提供的附加注释的答案
1.在 CMD 上解决问题:
@Domscheit 先生回答
c:\> chcp 65001
c:\> set NLS_LANG=.AL32UTF8
c:\> sqlplus ...
如果您不想每次都输入前 2 个命令,您可以通过注册表添加它们:
- 将代码页设置为 65001:
按照此 link 中的说明进行操作:
- 开始 -> 运行 -> regedit
- 转到
[HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor]
- 添加名为:Autorun 的新字符串值
- 将值更改为
chcp 65001
关闭
将 NLS_LANG 设置为 .AL32UTF8
- 开始 -> 运行 -> regedit
- 转到
[HKEY_LOCAL_MACHINE\Software\Oracle\{OracleHome#}]
- 添加名为的新字符串值:NLS_LANG
- 将值更改为
.AL32UTF8
- 关闭
现在当您打开 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