What you've is SQL injection and not a parameterized query. You may want to look at the RODBCext
package and its vignette.
To properly parameterize the query, you may do
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
)
This has big disadvantage, however, because sqlExecute
will run a query for each row in the data
argument (the list will be coerced to a data frame). If you have hundreds of elements in your item
vector, you will run hundreds of queries on your SQL instance, which may not be particularly efficient.
A less obvious way of doing this write a stored procedure to construct the query.
Your stored procedure in SQL might look like
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
You may need to fiddle with the convert
functions and some of the quotes, but it will work with
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
)
Unfortunately, this approach is still susceptible to problems with poorly formatted character strings being passed via item
, but it is likely faster than running hundreds of queries in the first approach I displayed.