Как несколько параметров привязки обрабатываются ROracle dbGetQuery/ dbSendQuery

В пакете ROracle dbSendQuery определяется как "dbSendQuery" (conn, statement, data=Null...), с аргументом данных, указанным как "data.frame, определяющий данные привязки".

Мой вопрос заключается в том, как аргумент данных читается функцией.

Например, я могу запустить следующую упрощенную функцию:

statement = “SELECT * FROM DATA WHERE DATE BETWEEN :START AND :END”

bind = data.frame(START = DT1, END = DT2)

DT1 = ‘01-jan-2020’
DT2 = ‘31-jan-2020’ 

dbSendQuery(con, statement = state, data = bind)

Однако я получаю сообщение об ошибке, когда пытаюсь запустить функцию с оператором SQL, который несколько раз вызывает одни и те же параметры привязки.

Например, если я попытаюсь запустить приведенный выше код со следующим упрощенным оператором, код не сработает:

statement = 
WITH DATA1 AS (SELECT * FROM TABLE1 WHERE DATE BETWEEN :START AND :END),
DATA2 AS (SELECT * FROM TABLE2 WHERE DATE BETWEEN :START AND :END),
DATA3 AS (SELECT * FROM DATA2 LEFT JOIN DATA1 ON DATA2.COLUMN = DATA1.COLUMN)

SELECT * 
FROM DATA3 
UNION ALL 
SELECT * 
FROM DATA3 A 
JOIN 
(SELECT * FROM TABLE2 
WHERE DATE BETWEEN :START AND :END) B
ON A.DATE = B.DATE"

Однако функция работает, если я запускаю dbSendQuery со следующим оператором и связываю:

statement = 
"WITH DATA1 AS (SELECT * FROM TABLE1 WHERE DATE BETWEEN :START1 AND :END1),
DATA2 AS (SELECT * FROM TABLE2 WHERE DATE BETWEEN :START2 AND :END2),
DATA3 AS (SELECT * FROM DATA2 LEFT JOIN DATA1 ON DATA2.COLUMN = DATA1.COLUMN)

SELECT * 
FROM DATA3 
UNION ALL 
SELECT * 
FROM DATA3 A 
JOIN 
(SELECT * FROM TABLE2 
WHERE DATE BETWEEN :START3 AND :END3) B
ON A.DATE = B.DATE"

bind = data.frame(START1, = DT1, START2 = DT1, START3 = DT1, END1 = DT2, END2 = DT2, END3 = DT2).

Хотя описанный выше метод работает, мне любопытно, почему я не могу запустить dbSendQuery с простым фреймворком данных.

bind = data.frame(START = DT1, END = DT2)

когда инструкция повторно использует одни и те же параметры привязки.

Я также пытался запустить dbSendQuery с

bind = data.frame(START = rep(DT1,3), END = rep(DT2,3)) 

ни к чему успеху.


person Vina_Song    schedule 21.03.2020    source источник
comment
Советы: отредактируйте свой вопрос и отформатируйте код. Используйте пример, который могут запустить другие люди, например, выберите из двойного. Дайте какие ошибки у вас есть. В общем, укажите версии ROracle, клиентских библиотек Oracle и БД Oracle.   -  person Christopher Jones    schedule 22.03.2020


Ответы (1)


После некоторого обсуждения с владельцами ROracle кажется, что вам нужна одна запись во фрейме данных связывания для каждого использования переменной связывания в операторе SQL. Это верно даже для именованных привязок:

bvn = as.numeric(1)
attr(bvn, "ora.parameter_name") <- "bv";
df <- data.frame(bvn, bvn)
dbGetQuery(con, "select * from dual where 1 = :bv and 1 = :bv", df)
person Christopher Jones    schedule 25.03.2020