使用RODBC进行参数化查询

10 sql r rodbc

我在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.

Dee*_*ter 9

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


jor*_*ran 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)
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是一个命名的参数值列表.

这就是我所知道的各种选择.