2015-08-02 2 views
2

У меня возникли трудности с передачей значения в dbSendQuery. Ниже мой код:Pass Parameter в RMySQL dbSendQuery

Параметр:

date_param <- '2014_02_02' 

Запрос:

pull <- dbSendQuery(test_db, "select distinct product_id, group 
           from test_table 
           where date between date_sub(",date_param,", interval 1 year) and ",date_param," ;") 

pulled_data <- fetch(pull, n=-1) 

Ошибки я получаю:

Error in is(object, Cl) : 
    internal error in RS_DBI_getResultSet: could not find resultSet in connection 

ли проблема с моим синтаксисом?

Спасибо.

ответ

3

Вам необходимо объединить инструкцию SQL в одну строку. Прямо сейчас вы передаете фрагменты как отдельные параметры. Попробуйте использовать paste(), чтобы создать свой статус.

pull <- dbSendQuery(test_db, paste("select distinct product_id, group 
          from test_table 
          where date between date_sub(",date_param,", interval 1 year) and ",date_param," ;")) 
+0

Спасибо за быстрый ответ. Я попробовал это, но он вернул нулевые результаты. Определенно есть данные для указанного диапазона. – BlackHat

1

Я знаю, что это очень старый вопрос, поэтому я надеюсь, что вы уже решили свою проблему. Как предположил @MrFlick, paste строит строку и позволяет передать ее как единственный параметр. Однако при этом вам нужно сделать некоторые семантики, чтобы убедиться, что даты указаны правильно. Поскольку у меня нет таблицы, которую вы обсуждаете (или информации о том, какие данные в ней), я построю простой запрос, чтобы показать, что происходит.

В настоящее время, что вы, вероятно, представления к базе данных что-то вроде:

date_param <- "2014_02_02" 

## currently submitting 
paste0("select distinct product_id, group from test_table where date between date_sub(", 
    date_param, ", interval 1 year) and ", date_param, " ;") 

#> [1] "select distinct product_id, group from test_table where date between date_sub(2014_02_02, interval 1 year) and 2014_02_02 ;" 


## analogous query 
paste0("select date_sub(", date_param, ", interval 1 year) as start , ", date_param, 
    " as end;") 
#> [1] "select date_sub(2014_02_02, interval 1 year) as start , 2014_02_02 as end;" 


## need to quote the dates 
paste0("select date_sub('", date_param, "', interval 1 year) as start , '", 
    date_param, "' as end;") 
#> [1] "select date_sub('2014_02_02', interval 1 year) as start , '2014_02_02' as end;" 

Если скопировать и вставить последний запрос в редакторе SQL, он должен работать так, как вы ожидаете (уведомления цитаты вокруг дат).

Преимущество использования paste (или paste0 - без разделителя) заключается в том, что вы можете точно отображать запрос, который отправляется, и тестировать его самостоятельно в редакторе SQL. Недостатком является раздражающее поведение котировок и риск для SQL Injection (а также отсутствие безопасности типа). Решение лучше должно использовать переменную подстановку, которая немного отличается от реализации (RMySQL и RMariaDB используют ?, RPostgreSQL и RPostgres используют $1, $2, $3 и т. Д.). См. DBI Spec для получения дополнительной информации. Вы также можете получить выигрыш в производительности, предварительно подготовив запрос.

Следует также отметить, что пакет RMySQL постепенно прекращается - RMariaDB совместим как с MySQL, так и с MariaDB, и именно здесь происходит будущее развитие. (Из моего исследования, это выглядит как RMySQL пакет не имеет большую поддержку подготовленных запросов, как это)

library(RMariaDB) 

date_param <- "2014_02_02" 

conn <- dbConnect(MariaDB(), ...) 

query <- "select date_sub(?, interval 1 year) as start, date(?) as end;" 

rs <- dbSendQuery(conn, query, list(date_param, date_param)) 
dbFetch(rs) 
#>  start  end 
#> 1 2013-02-02 2014-02-02 
dbClearResult(rs) 
#> [1] TRUE 
Смежные вопросы