【问题标题】:ROracle: dbGetQuery works but dbListTables and other functions do notROracle:dbGetQuery 有效,但 dbListTables 和其他函数无效
【发布时间】:2017-01-15 10:28:48
【问题描述】:

我安装了 ROracle(按照directions in the package)并成功连接到我们的 Oracle 数据库。

我可以使用dbGetQuery 运行查询,并获得很好的结果,例如:

> dbGetQuery(con, "select count(*) from table_name")
  COUNT(*)
1     6111

但是,其他一些 DBI/ROracle 辅助函数没有给出任何结果:

> dbListTables(con)
character(0)

> dbReadTable(con, "table_name")
Error in .oci.GetQuery(con, qry) : 
  ORA-00942: table or view does not exist

任何想法可能是什么原因?

【问题讨论】:

    标签: r oracle r-dbi roracle


    【解决方案1】:

    在这两种情况下,如果我指定 schema 参数,它们都对我有用,即

    dbListTables(con, schema = "my_schema")
    dbReadTable(con,"table_name",schema = "my_schema")
    

    此外,从阅读 ?dbListTables 可以看出,它具有 allfull 参数,用于控制是否查看所有架构,以及是否返回完整的架构名称或仅返回表名称。

    【讨论】:

    • 其实我发现schema不是必须的,但是dbReadTable中的表名应该是大写的(而不是dbGetQuery中的)。请参阅下面的答案。
    【解决方案2】:

    花了太多时间试图弄清这个问题的真相后,我想记录下答案以供后人参考。在dbReadTable 中实际上不需要架构,但是将表名以大写形式表示。也就是说,调用应该是

    dbReadQuery(con, "TABLE_NAME")
    

    为什么?

    要了解 dbReadTable 与带有 select * from table 调用的 dbGetQuery 有何不同,我挖掘了源代码:

    > showMethods("dbReadTable")
    Function: dbReadTable (package DBI)
    conn="OraConnection", name="character"
    

    所以这是一个 S4 方法。我们使用带有上述签名的getMethod

    > getMethod("dbReadTable", signature = c(conn = "OraConnection", name = "character"))
    Method Definition:
    
    function (conn, name, ...) 
    {
        .local <- function (conn, name, schema = NULL, row.names = NULL, 
            ...) 
        .oci.ReadTable(conn, name, schema = schema, row.names = row.names)
        .local(conn, name, ...)
    }
    <environment: namespace:ROracle>
    

    .oci.ReadTable 可以在 ROracle 的源代码中找到 here。它所做的只是检查参数的有效性,调用dbGetQuery,并设置行名。相关部分(调用dbGetQuery)在这里:

    # form name
    if (is.null(schema))
      tab <- sprintf('"%s"', name)
    else
      tab <- sprintf('"%s"."%s"', schema, name)
    
    # read table
    qry <- paste('select *',
                   'from', tab)
    res <- .oci.GetQuery(con, qry)
    

    请注意,如果未指定架构,则使用不带“架构”的表名。字首。但是,sprintf 为表名生成带引号的字符串,quoted table names are case sensitive! (dbGetQuery 只是传递一个可以是小写的不带引号的表名。)

    这就是为什么 dbGetQuery(con, "select count(*) from table_name") 有效,dbReadQuery(con, "TABLE_NAME") 也有效,但 dbReadQuery(con, "table_name") 无效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-05
      • 2015-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-04
      • 2019-03-27
      • 1970-01-01
      相关资源
      最近更新 更多