ROracle: dbGetQuery работает, а dbListTables и другие функции — нет.

Я установил ROracle (следуя указаниям в пакете) и успешно подключился к наша база данных 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

Есть идеи, в чем может быть причина?


person Victor Kostyuk    schedule 07.09.2016    source источник


Ответы (2)


В обоих случаях они у меня работают, если я указываю аргумент schema, т.е.

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

Кроме того, при чтении ?dbListTables видно, что у него есть аргументы all и full, которые определяют, следует ли искать во всех схемах и следует ли возвращать полное имя схемы или только имя таблицы.

person joran    schedule 07.09.2016
comment
Собственно, я понял, что схема не нужна, но имя таблицы должно быть в верхнем регистре в dbReadTable (но не в dbGetQuery). Смотрите мой ответ ниже. - person Victor Kostyuk; 08.09.2016

Потратив слишком много времени, пытаясь разобраться в этом вопросе, я хочу записать ответ для потомков. На самом деле наличие схемы в dbReadTable не обязательно, но нужно указывать имя таблицы в верхнем регистре. То есть вызов должен быть

dbReadQuery(con, "TABLE_NAME")

Почему?

Чтобы узнать, чем dbReadTable отличается от dbGetQuery с вызовом select * from table, я откопал источник:

> 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. Все, что он делает, это проверяет допустимость аргументов, вызывает 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 создает строку в кавычках для имени таблицы и имена таблиц в кавычках чувствительны к регистру! (dbGetQuery просто передает имя таблицы без кавычек, которое может быть строчным.)

Вот почему dbGetQuery(con, "select count(*) from table_name") работает, как и dbReadQuery(con, "TABLE_NAME"), но dbReadQuery(con, "table_name") нет.

person Victor Kostyuk    schedule 07.09.2016