dbplyr Oracle 别名限制数据库
dbplyr Oracle alias limit database
经过漫长的故障排除过程后,我终于让 RStudio 使用即时客户端连接到我的工作 Oracle 数据库。这样做的动机是使用 dbplyr 来完成我的大部分查询。但是,我无法通过 dbplyr 发送任何查询,因为所有列和 table 名称都非常长并导致 ORA-00972: identifier is too long.
示例错误
test <- tbl(con, "long_shcema_name.very_long_and_descriptive_name") %>%
select(a_column)
Error: nanodbc/nanodbc.cpp:1617: 42000: [Oracle][ODBC][Ora]ORA-00972: identifier is too long
<SQL> 'SELECT *
FROM ("long_shcema_name.very_long_and_descriptive_name") "zzz7"
WHERE (0 = 1)'
我认为问题与驱动程序有关。我的工作使用 Oracle 12.2,它具有更大的标识符上限,但 dbGetQuery 在 instantclient
上运行良好
没有 dbplyr 的工作示例
dbGetQuery(con,'
select "a_column"
from
long_shcema_name.very_long_and_descriptive_name')
a_column
1
0
2
.
.
.
这给了我想要的结果。
有解决办法吗?
我有点生气。我花了将近三周的时间才使用即时客户端建立了与我的工作数据库的 odbc 连接。我能够从一开始就使用 RODBC 和 ROracle 进行查询,但我想使用 dplyr。它最终无法正常工作,我没有太多精力去弄清楚为什么。在这一点上,我们将不胜感激任何帮助。
问题很可能是文件名不长(除非您的 table 名称超过 30 个字符,请参阅 here) but the use of a schema. Oracle can use double quotes to identify database, schema and table names (ref). Square brackets are sometimes used for this purpose too (ref)。
查看产生错误消息的 SQL:
SELECT *
FROM ("long_schema_name.very_long_and_descriptive_name") "zzz7"
WHERE (0 = 1)
这很可能被解释为:
- 数据库={默认}
- 架构 = {空}
- table = long_schema_name.very_long_and_descriptive_name
而不是:
- 数据库={默认}
- 架构 = long_schema_name
- table = very_long_and_descriptive_name
正如@Wil 评论的那样,您可以使用 in_schema
函数解决这个问题。如果你尝试:
test <- tbl(con, in_schema("long_schema_name","very_long_and_descriptive_name") %>%
select(a_column)
那么show_query(test)
应该return:
SELECT *
FROM ("long_schema_name"."very_long_and_descriptive_name") "zzz7"
WHERE (0 = 1)
请注意这与第一个查询的不同之处在于在句号的两边添加了双引号。
经过漫长的故障排除过程后,我终于让 RStudio 使用即时客户端连接到我的工作 Oracle 数据库。这样做的动机是使用 dbplyr 来完成我的大部分查询。但是,我无法通过 dbplyr 发送任何查询,因为所有列和 table 名称都非常长并导致 ORA-00972: identifier is too long.
示例错误
test <- tbl(con, "long_shcema_name.very_long_and_descriptive_name") %>%
select(a_column)
Error: nanodbc/nanodbc.cpp:1617: 42000: [Oracle][ODBC][Ora]ORA-00972: identifier is too long
<SQL> 'SELECT *
FROM ("long_shcema_name.very_long_and_descriptive_name") "zzz7"
WHERE (0 = 1)'
我认为问题与驱动程序有关。我的工作使用 Oracle 12.2,它具有更大的标识符上限,但 dbGetQuery 在 instantclient
上运行良好没有 dbplyr 的工作示例
dbGetQuery(con,'
select "a_column"
from
long_shcema_name.very_long_and_descriptive_name')
a_column
1
0
2
.
.
.
这给了我想要的结果。
有解决办法吗?
我有点生气。我花了将近三周的时间才使用即时客户端建立了与我的工作数据库的 odbc 连接。我能够从一开始就使用 RODBC 和 ROracle 进行查询,但我想使用 dplyr。它最终无法正常工作,我没有太多精力去弄清楚为什么。在这一点上,我们将不胜感激任何帮助。
问题很可能是文件名不长(除非您的 table 名称超过 30 个字符,请参阅 here) but the use of a schema. Oracle can use double quotes to identify database, schema and table names (ref). Square brackets are sometimes used for this purpose too (ref)。
查看产生错误消息的 SQL:
SELECT *
FROM ("long_schema_name.very_long_and_descriptive_name") "zzz7"
WHERE (0 = 1)
这很可能被解释为:
- 数据库={默认}
- 架构 = {空}
- table = long_schema_name.very_long_and_descriptive_name
而不是:
- 数据库={默认}
- 架构 = long_schema_name
- table = very_long_and_descriptive_name
正如@Wil 评论的那样,您可以使用 in_schema
函数解决这个问题。如果你尝试:
test <- tbl(con, in_schema("long_schema_name","very_long_and_descriptive_name") %>%
select(a_column)
那么show_query(test)
应该return:
SELECT *
FROM ("long_schema_name"."very_long_and_descriptive_name") "zzz7"
WHERE (0 = 1)
请注意这与第一个查询的不同之处在于在句号的两边添加了双引号。