问题描述
在从 Oracle 数据库查询包含阿拉伯数据的表时,R 无法编码正确的字符。
以下是我尝试执行的操作的示例:
library(DBI)
library(dplyr)
#My local environment is set to arabic
Sys.setlocale("LC_CTYPE","arabic")
# My connection string to database
db_conn <- dbConnect(odbc::odbc(),"my_db",encoding = "utf-8")
# Extracting data
my_table <- tbl(db_conn,"my_table")
result <-
my_table %>%
filter(ID == 100010456) %>%
select(ID,ADDRESS_1) %>%
collect()
这是我得到的结果:
不过这是数据库中的实际数据:
一些进一步的说明:
- 数据库的NLS_CHaraCTERSET是AR8ISO8859P6
- 我尝试过使用不同编码选项(windows-1252、utf-8)的 dbconnect
- 我尝试在 dbconnect 中添加字符集选项
- 我曾尝试使用 dbGetQuery 显式检索结果
解决方法
这里有几种不同的尝试方法。请评论他们是否提供帮助。
1.查询数据库的编码是什么
This 问题从以下 SQL 代码片段开始,用于获取 PostgreSQL 数据库中的编码(它有几个可能也有帮助的答案):
dbGetQuery(con,"SHOW CLIENT_ENCODING")
# client_encoding
# 1 UTF8
如果您没有使用 PostgreSQL 数据库,那么您使用的数据库可能会有一个等效的命令。
阅读 ?odbc::dbConnect
的文档,encoding
是您的数据库的文本编码(如果不是 UTF8)。并且字符串总是以 UTF-8 编码返回。
鉴于您注意到数据库的字符集是 AR8ISO8859P6,我猜客户端编码将返回类似 "ar8-iso8859"
的内容,这是用于连接的术语。例如:
db_conn <- dbConnect(odbc::odbc(),"my_db",encoding = "ar8-iso8859")
2.测试每个可用的编码
您在评论中提到有 232 种可能的编码。 This 链接显示了一个函数,用于测试两种不同编码的输出有何不同。
如果您无法从数据库中获取编码,那么迭代并测试所有编码可能是最佳选择。也许是这样的:
testEncoding <- function(encoding){
# My connection string to database
db_conn <- dbConnect(odbc::odbc(),encoding = encoding)
# Extracting data
result <- tbl(db_conn,"my_table") %>%
filter(ID == 100010456) %>%
select(ADDRESS_1) %>%
collect()
# disconnect & return
dbDisconnect(db_conn)
return(result[1,2])
}
list_of_encodings <- stringi::stri_enc_list()
for(encoding in list_of_encodings){
print(paste(encoding[1]," | ",testEncoding(encoding[1])))
}
3.运行测试写出一个中间文本文件
该数据库应允许您将数据导出为 csv 或等效文件。然后可以使用标准方法将该文件读入 R:
- 将包含阿拉伯字符的数据子集导出到纯文本文件(很可能是 UTF-8)。
- 检查文件内容以确认出现阿拉伯字符。
- 将纯文本文件导入 R。检查导入的数据框。
- 将导入的数据框从 R 导出回纯文本 (UTF-8)。
- 检查第二个文件的内容以确认出现阿拉伯字符。
这种方法应该让您对 R 和数据库之间的通信失败的地方有一些额外的了解。您是否需要特定设置才能从数据库中导出阿拉伯字符?将它们导入到 R 中? R 是否正确读写阿拉伯字符,但无法显示它们?