【问题标题】:How do I remove embedded quotes from sqlInterpolate function of R?如何从 R 的 sqlInterpolate 函数中删除嵌入的引号?
【发布时间】:2018-01-24 13:32:03
【问题描述】:

我正在尝试使用DBI::sqlInterpolate 函数生成一堆 SQL 脚本,但由于脚本嵌入了与 R 变量一起返回的引号,因此不断出现 SQL 错误。

代码如下:

> 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]

【问题讨论】:

  • 使用sqldf 让sql查询更简单

标签: r sql-injection rmysql r-dbi


【解决方案1】:

1) gsubfn gsubfn 包中的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)

【讨论】:

  • 太棒了!目前,我使用了 sprintf 解决方案,虽然我猜它对 SQL 注入攻击没有帮助,对吧?
  • 这里的所有 3 个解决方案都只适用于纯文本,因此它们将注入替换文本中的任何内容。
猜你喜欢
  • 1970-01-01
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-19
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多