利用RJDBC查询Oracle数据库

woobm2wo  于 2023-11-17  发布在  Oracle
关注(0)|答案(1)|浏览(149)

使用RJDBC连接到服务器,该服务器托管Oracle(11.2g)数据库,我可以使用DBI::dbGetQuery()从查询中获取结果。RJDBC::dbGetTables()和DBI::dbListTables()都可以工作。
然而,我不能使用dqur::tbl()来处理数据库表,就像它们是内存中的对象一样,例如使用dqur动词。我在以前的工作中能够做到这一点,并且非常喜欢它:-)

tbl(con, in_schema("abc","TABLE_NAME"))

字符串
结果是:

Error in `dplyr::db_query_fields()`:
! Can't query fields.
Caused by error in `dbSendQuery()`:
! Unable to retrieve JDBC result set
  JDBC ERROR: ORA-00933: SQL command not properly ended

  Statement: SELECT *
FROM "abc"."TABLE_NAME" AS "q01"
WHERE (0 = 1)


我已经尝试了以下从https://solutions.posit.co/connections/db/databases/oracle/

sql_translation.JDBCConnection <- dbplyr:::sql_translation.Oracle
sql_select.JDBCConnection <- dbplyr:::sql_query_select.Oracle
sql_subquery.JDBCConnection <- dbplyr:::sql_query_wrap.Oracle


但现在

tbl(con, in_schema("abc","TABLE_NAME"))


结果是:

Error in `collect()`:
! Failed to collect lazy table.
Caused by error in `dbSendQuery()`:
! Unable to retrieve JDBC result set
  JDBC ERROR: ORA-00933: SQL command not properly ended

  Statement: SELECT *
FROM ("abc"."TABLE_NAME") 
FETCH FIRST 11 ROWS ONLY


因为我觉得我们的oracle版本不喜欢“FETCH FIRST”,所以我用这个修改了发送的查询:

trace(dbplyr:::sql_query_select.Oracle, edit=TRUE)


"FETCH FIRST ", <limit>, "ONLY"替换为"WHERE ROWNUM <", <limit>"。这将返回一个结果!但是:1)R认为前10行是所有的(并且不知道查询是懒惰的),2)dyplr::filter不工作,因为它返回:

Error in `collect()`:
! Failed to collect lazy table.
Caused by error in `dbSendQuery()`:
! Unable to retrieve JDBC result set
  JDBC ERROR: ORA-00933: SQL command not properly ended

  Statement: SELECT *
FROM ("abc"."TABLE_NAME") 
WHERE ("variable" = x)
WHERE ROWNUM < 11


那么,如何实现davr动词工作,R执行懒惰查询(并了解它)?
谢谢你的帮助!

7qhs6swi

7qhs6swi1#

SELECT *
FROM "abc"."TABLE_NAME" AS "q01"
WHERE (0 = 1)

字符串
是无效的,因为Oracle禁止你使用AS作为表别名;如果你让R用正确的方言生成SQL,这样它就不会在表别名之前使用AS,那么它应该可以工作。

SELECT *
FROM ("abc"."TABLE_NAME") 
WHERE ("variable" = x)
WHERE ROWNUM < 11


无效,因为您有两个WHERE子句;第二个WHERE应该是AND
R认为前10行是全部
如果你将一个静态过滤器硬编码到一个查询中,将输出限制为ROWNUM < 11,那么你将只得到10行(这些行将是匹配过滤条件的前10个随机行,而不是特定顺序的10行)。所以,R是正确的,这就是10行硬编码过滤器的全部内容。
如果你想对一个查询进行分页,那么你需要(例如,获取第101-110行):

SELECT column1,
       column2,
       column3
FROM   (
  SELECT column1,
         column2,
         column3,
         ROWNUM AS rn
  FROM   (
    SELECT column1,
           column2,
           column3
    FROM   "abc"."TABLE_NAME"
    WHERE  "variable" = x
    ORDER BY something
  )
  WHERE  ROWNUM <= 110
)
WHERE rn > 100

  • (先排序,然后按上限过滤,使用内联视图具体化行号,然后使用具体化的行号按下限过滤。)*

相关问题