DBI 包中的 dbWriteTable 函数更改字符编码
dbWriteTable function from DBI package changes character encoding
我在使用 DBI 包(也是 ROracle 包的一部分)中的 dbWriteTable 函数时遇到问题。
我正在尝试将 data.frame 导出到 Oracle 服务器,其中 data.frame 的列具有混合编码(“未知”和“UTF-8”)。如果我将所有行导出到 Oracle 服务器,则带重音的字符(即 UTF-8 字符)在 Oracle 服务器上变为非 UTF-8 字符,而如果我仅导出那些具有 UTF-8 编码的行,则这些字符是在 Oracle 上正确显示。
在我看来,dbWriteTable 函数将编码降级到列中找到的最低级别。是 dbWriteTable 函数中的错误还是我错过了正确设置编码?有人知道该问题的解决方法吗?
重现我遇到的问题的代码:
# Library
library("ROracle")
# Parameters
oracle_username <- "USER"
oracle_password <- "PASSWORD"
oracle_table_name <- "PLEASE_GIVE_A_NAME"
# Oracle kapcsolat
connection_string <- "THIS_IS_COMPANY_SPECIFIC"
drv <- DBI::dbDriver("Oracle")
# Setting up the connection
con <- DBI::dbConnect(drv, username = oracle_username, password = oracle_password, dbname = connection_string)
# Table to be exported to Oracle
dt_example <- as.data.frame(STRING = c("Unknown Urszula", "UTF-8 Uránia"))
# Checking the encoding
Encoding(dt_example$STRING)
# Exporting all rows
DBI::dbExecute(con, paste("drop table", toupper(oracle_table_name)))
DBI::dbWriteTable(con, name = toupper(oracle_table_name), value = dt_example, overwrite = TRUE, append = FALSE)
# --> The result on the server is Unknown Urszula and UTF-8 Ur??nia
# Exporting only the row with UTF-8 encoding
DBI::dbExecute(con, paste("drop table", toupper(oracle_table_name)))
DBI::dbWriteTable(con, name = toupper(oracle_table_name), value = dt_example[2, ], overwrite = TRUE, append = FALSE)
# --> The result on the server is UTF-8 Uránia
我有以下系统/环境:
> R.version
_
platform x86_64-suse-linux-gnu
arch x86_64
os linux-gnu
system x86_64, linux-gnu
status
major 3
minor 5.0
year 2018
month 04
day 23
svn rev 74626
language R
version.string R version 3.5.0 (2018-04-23)
> Sys.getlocale()
[1] "LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8;LC_COLLATE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_MESSAGES=en_US.UTF-8;LC_PAPER=en_US.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_US.UTF-8;LC_IDENTIFICATION=C"
> Sys.getenv(c("LANG", "ORACLE_HOME"))
LANG ORACLE_HOME
"en_US.UTF-8" "/usr/lib/oracle/12.1/client64/lib"
NLS_LANG参数在操作系统上设置为AMERICAN_AMERICA.EE8ISO8859P2
Oracle 服务器具有以下 NLS 设置:
select * from V$NLS_PARAMETERS;
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE AMERICAN
NLS_CHARACTERSET EE8ISO8859P2
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY $
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
感谢任何帮助!先谢谢你了!
我遇到了类似的问题:data.frame 带有西班牙文字母,例如 ñ
字符。当我使用 dbWriteTable
和 ROracle
创建 table 时,此字符的编码不正确。
如果我使用 Encoding(myData[[col]]) <- "UTF-8"
在 R 中看起来不错,但在 Oracle 中是错误的,所以我将字符 data.frame 列转换为 local
然后转换为 latin1
现在在 Oracle 中看起来不错。
for (col in colnames(myData)){
if (class(myData[[col]]) == "numeric"){
next()
} else {
Encoding(myData[[col]]) <- "UTF-8"
myData[[col]] <- enc2native(myData[[col]])}
Encoding(myData[[col]]) <- "latin1"
}
对于上下文...我的 Oracle 数据库编码是:
SELECT * FROM NLS_DATABASE_PARAMETERS;
NLS_CHARACTERSET = WE8ISO8859P1
我有一个 .Renviron
这个条目:
NLS_LANG=".WE8ISO8859P1"
所以,当我使用 dbGetQuery
时,我得到了正确的字符。
我在使用 DBI 包(也是 ROracle 包的一部分)中的 dbWriteTable 函数时遇到问题。
我正在尝试将 data.frame 导出到 Oracle 服务器,其中 data.frame 的列具有混合编码(“未知”和“UTF-8”)。如果我将所有行导出到 Oracle 服务器,则带重音的字符(即 UTF-8 字符)在 Oracle 服务器上变为非 UTF-8 字符,而如果我仅导出那些具有 UTF-8 编码的行,则这些字符是在 Oracle 上正确显示。
在我看来,dbWriteTable 函数将编码降级到列中找到的最低级别。是 dbWriteTable 函数中的错误还是我错过了正确设置编码?有人知道该问题的解决方法吗?
重现我遇到的问题的代码:
# Library
library("ROracle")
# Parameters
oracle_username <- "USER"
oracle_password <- "PASSWORD"
oracle_table_name <- "PLEASE_GIVE_A_NAME"
# Oracle kapcsolat
connection_string <- "THIS_IS_COMPANY_SPECIFIC"
drv <- DBI::dbDriver("Oracle")
# Setting up the connection
con <- DBI::dbConnect(drv, username = oracle_username, password = oracle_password, dbname = connection_string)
# Table to be exported to Oracle
dt_example <- as.data.frame(STRING = c("Unknown Urszula", "UTF-8 Uránia"))
# Checking the encoding
Encoding(dt_example$STRING)
# Exporting all rows
DBI::dbExecute(con, paste("drop table", toupper(oracle_table_name)))
DBI::dbWriteTable(con, name = toupper(oracle_table_name), value = dt_example, overwrite = TRUE, append = FALSE)
# --> The result on the server is Unknown Urszula and UTF-8 Ur??nia
# Exporting only the row with UTF-8 encoding
DBI::dbExecute(con, paste("drop table", toupper(oracle_table_name)))
DBI::dbWriteTable(con, name = toupper(oracle_table_name), value = dt_example[2, ], overwrite = TRUE, append = FALSE)
# --> The result on the server is UTF-8 Uránia
我有以下系统/环境:
> R.version
_
platform x86_64-suse-linux-gnu
arch x86_64
os linux-gnu
system x86_64, linux-gnu
status
major 3
minor 5.0
year 2018
month 04
day 23
svn rev 74626
language R
version.string R version 3.5.0 (2018-04-23)
> Sys.getlocale()
[1] "LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8;LC_COLLATE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_MESSAGES=en_US.UTF-8;LC_PAPER=en_US.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_US.UTF-8;LC_IDENTIFICATION=C"
> Sys.getenv(c("LANG", "ORACLE_HOME"))
LANG ORACLE_HOME
"en_US.UTF-8" "/usr/lib/oracle/12.1/client64/lib"
NLS_LANG参数在操作系统上设置为AMERICAN_AMERICA.EE8ISO8859P2
Oracle 服务器具有以下 NLS 设置:
select * from V$NLS_PARAMETERS;
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE AMERICAN
NLS_CHARACTERSET EE8ISO8859P2
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY $
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
感谢任何帮助!先谢谢你了!
我遇到了类似的问题:data.frame 带有西班牙文字母,例如 ñ
字符。当我使用 dbWriteTable
和 ROracle
创建 table 时,此字符的编码不正确。
如果我使用 Encoding(myData[[col]]) <- "UTF-8"
在 R 中看起来不错,但在 Oracle 中是错误的,所以我将字符 data.frame 列转换为 local
然后转换为 latin1
现在在 Oracle 中看起来不错。
for (col in colnames(myData)){
if (class(myData[[col]]) == "numeric"){
next()
} else {
Encoding(myData[[col]]) <- "UTF-8"
myData[[col]] <- enc2native(myData[[col]])}
Encoding(myData[[col]]) <- "latin1"
}
对于上下文...我的 Oracle 数据库编码是:
SELECT * FROM NLS_DATABASE_PARAMETERS;
NLS_CHARACTERSET = WE8ISO8859P1
我有一个 .Renviron
这个条目:
NLS_LANG=".WE8ISO8859P1"
所以,当我使用 dbGetQuery
时,我得到了正确的字符。