什么是SQL注入而不是参数化查询。您可能需要查看RODBCext
包装及其vignette。
要正确参数化查询,你可以做
library(RODBC)
library(RODBCext)
channel = odbcConnect("VerticaDB")
query = paste0("select * from Item_History ",
"where Item_Exp_Date between ? and ? ",
"and Item_Code = ?")
item <- c("A1", "A2", "B1", "B2")
x <- 3
y <- 10 # I don't actually know what your x and y are, but hopefully you get the idea
sqlExecute(
channel = channel,
query = query,
data = list(x = rep(x, length(item)),
y = rep(y, length(item)),
item = item),
fetch = TRUE,
stringsAsFactors = FALSE
)
这大的缺点,但是,因为sqlExecute
将在data
参数运行于各行的查询(该列表将被强制转换为数据帧)。如果您的item
向量中有数百个元素,那么您将在SQL实例上运行数百个查询,这可能不是特别有效。
这样做的一个不太明显的方法是编写一个存储过程来构造查询。
在SQL存储过程可能看起来像
CREATE PROCEDURE schema.specialQuery
@x int;
@y int;
@in varchar(2000);
AS
BEGIN
DECLARE @query = varchar(8000);
SET @query = 'select * from Item_History ' +
'where Item_Exp_Date between ' + convert(@x, varchar(10)) +
' and ' + convert(@y, varchar(10)) +
' and Item_Code IN (' + @in ')'
EXEC @query
END
GO
您可能需要与convert
功能和一些引号的摆弄,但它会与
sqlExecute(
channel = channel,
query = "EXECUTE schema.specialQuery @x = ?, @y = ?, @in = ?",
data = list(x = x,
y = y,
in = sprintf("'%s'", paste0(item, collapse = "', '"))),
fetch = TRUE,
stringsAsFactors = FALSE
)
不幸的是,这种方法工作仍然容易受到通过item
传递格式不正确的字符串的问题,但它可能比在我显示的第一种方法中运行数百个查询更快。
到OP和未来的读者 - 请注意OP的尝试或接受的答案都不是真正的参数化SQL查询。 @Benjamin是一个更好的尝试,而其他人只是简单地连接一个动态SQL字符串。 – Parfait