2017-08-16 38 views
1

我正嘗試使用DBI::sqlInterpolate函數生成一堆SQL腳本,但隨着腳本嵌入與R變量一起返回的引號,會不斷獲取SQL錯誤。如何從R的sqlInterpolate函數中刪除嵌入的引號?

這裏是代碼:

> x<-'state_transtions' 
> y<-'transition_time' 
> script<-"select * from ?x WHERE DATE(?y)> DATE_SUB(NOW(), INTERVAL 1 DAY)" 
> sqlInterpolate(ANSI(),script,x=x,y=y) 
#<SQL> select * from 'state_transtions' WHERE DATE('transition_time')> DATE_SUB(NOW(), INTERVAL 1 DAY) 

正如你看到的我產生過R代碼所需的SQL表名和列名。因此注入值(?x,?y)作爲變量傳遞。

我擡頭看這個最接近找到解決辦法的鏈接,但說實話,我不明白。 [https://rstats-db.github.io/DBI/reference/sqlParseVariables.html#examples]

+0

使用'sqldf'使sql查詢更容易 –

回答

1

1)gsubfngsubfn在gsubfn包中可以做替換。這裏的正則表達式匹配問號後面跟單詞字符,然後它使用第二個參數中定義的對應關係對由括號內的部分匹配的正則表達式部分執行替換。

library(gsubfn) 

gsubfn("[?](\\w+)", list(x = x, y = y), script) 

給出以下:

[1] "select * from state_transtions WHERE DATE(transition_time)> DATE_SUB(NOW(), INTERVAL 1 DAY)" 

2)FN $該gsubfn包還提供fn$其可以前綴的任何功能,並且將其參數給予相同的結果執行字符串內插。 identity可以用任何其他合適的R函數代替。

它將字符串中的$ x(其中x可以是僅由字母和數字組成的任何名稱)替換爲名爲x的變量的內容。

library(gsubfn) 

script2 <- "select * from $x WHERE DATE($y)> DATE_SUB(NOW(), INTERVAL 1 DAY)" 
fn$identity(script2) 

的gsubfn包由sqldf自動加載,並經常與它一起使用的話,例如,

library(sqldf) 

var <- "Time" 
fn$sqldf("select $var from BOD where $var > `mean(1:7)`") 

,並提供:

Time 
1 5 
2 7 

3)的sprintf它也是可能做到這一點,沒有任何包只使用sprintf

sprintf("select * from %s WHERE DATE(%s)> DATE_SUB(NOW(), INTERVAL 1 DAY)", x, y) 
+0

太棒了!目前,我已經使用了sprintf解決方案,儘管我不會猜測SQL注入攻擊的幫助,不是嗎? –

+1

這裏的所有3種解決方案都只能處理純文本,所以它們會在替換文本中注入任何內容。 –