什麼是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