使用RODBC进行参数化查询

时间:2013-04-23 20:31:09

标签: sql r rodbc

我在R中有一个我想传递给数据库的变量。在阅读Google搜索结果时,我可以使用paste许多建议,但由于SQL注入漏洞,这是不安全的。我宁愿喜欢这样的东西:

x <- 42
sqlQuery(db, 'SELECT Id, Name FROM People WHERE Age > ?;', bind=c(x))

是否可以在RODBC中使用参数化查询?如果没有,是否有支持它们的替代库?

我正在使用SQL Server,RODBC 1.3-6和R 3.0.0。

2 个答案:

答案 0 :(得分:9)

Mateusz Zoltak于2014年撰写RODBCext一揽子计划(基于Brian Ripley和Michael Lapsley的工作):

conn = odbcConnect('MyDataSource')

sqlPrepare(conn, "SELECT * FROM myTable WHERE column = ?")
sqlExecute(conn, 'myValue')
sqlFetchMore(conn)

来源:http://cran.r-project.org/web/packages/RODBCext/vignettes/Parameterized_SQL_queries.html

答案 1 :(得分:5)

这些是我所知道的使用RODBC的选项。我知道 RSQLite原生支持参数绑定,但也就是说 通常不是大多数人的选择。

# Note that sprintf doesn't quote character values. The quotes need
# to be already in the sql, or you have to add them yourself to the
# parameter using paste().
q <- "select * from table where val1 = '%s' and val2 < %d and val3 >= %f"
sprintf(q,"Hey!",10,3.141)

# The gsub route means you can't easily use a single placeholder
# value.
q <- "select * from table where val1 = '?' and val2 < ? and val3 >= ?"
gsub("?","Value!",q,fixed = TRUE)

我为我的工作处理了许多需要各种问题的预制查询 参数。因为在我的情况下我只有SELECT特权,我就是 只有运行我的代码的人,我真的不需要担心验证。

所以我基本上已经走了gsub路线,以便能够存储所有路线 我的查询在单独的.sql文件中。这是因为查询通常很长 足够让他们在我的.R文件中保持笨拙。让它们分开 通过格式化和突出显示,我可以更轻松地编辑和维护它们 更适合SQL。

所以我编写了一些从.sql文件中读取查询的小函数 并绑定任何参数。我用带有冒号的参数编写查询, 即:param1::param2:

然后我用这个函数来读取.sql文件:

function (path, args = NULL) 
{
    stopifnot(file.exists(path))
    if (length(args) > 0) {
        stopifnot(all(names(args) != ""))
        sql <- readChar(path, nchar = file.info(path)$size)
        p <- paste0(":", names(args), ":")
        sql <- gsub_all(pattern = p, replacement = args, x = sql)
        return(sql)
    } else {
        sql <- readChar(path, nchar = file.info(path)$size)
        return(sql)
    }
}

其中gsub_all基本上只是for循环的包装器 参数和args是参数值的命名列表。

这是我所知道的选项范围。