我在R中有一个变量,我想传递给数据库.在阅读谷歌搜索结果时,我可以使用paste
许多建议,但由于SQL注入漏洞,这是不安全的.我更喜欢这样的东西:
x <- 42
sqlQuery(db, 'SELECT Id, Name FROM People WHERE Age > ?;', bind=c(x))
Run Code Online (Sandbox Code Playgroud)
是否可以使用RODBC参数化查询?如果没有,是否有支持它们的替代库?
我使用的是SQL Server,RODBC 1.3-6和R 3.0.0.
Mateusz Zoltak RODBCext
于2014年撰写了一揽子计划(基于Brian Ripley和Michael Lapsley的工作):
conn = odbcConnect('MyDataSource')
sqlPrepare(conn, "SELECT * FROM myTable WHERE column = ?")
sqlExecute(conn, 'myValue')
sqlFetchMore(conn)
Run Code Online (Sandbox Code Playgroud)
资料来源:http://cran.r-project.org/web/packages/RODBCext/vignettes/Parameterized_SQL_queries.html
这些是我所知道的使用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)
Run Code Online (Sandbox Code Playgroud)
我为我的工作处理了许多需要各种参数的预制查询.因为在我的情况下我只有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)
}
}
Run Code Online (Sandbox Code Playgroud)
where gsub_all
基本上只是参数的for循环的包装器,args
是一个命名的参数值列表.
这就是我所知道的各种选择.