あなたはSQLインジェクションであり、パラメータ化されたクエリではありません。 RODBCext
パッケージとそのvignetteを見るとよいでしょう。 sqlExecute
は(リストは、データフレームに強制変換されますdata
引数の各行に対してクエリを実行しますので、適切にクエリをパラメータ化する
、あなたが
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
)
を行うことがありますが、これは、しかし、大きな欠点を持っています)。 item
ベクトルに何百もの要素がある場合、SQLインスタンスで何百ものクエリを実行しますが、これは特に効率的ではありません。
これを実行するあまり明白な方法では、ストアドプロシージャを作成してクエリを構築します。
SQLであなたのストアドプロシージャは、あなたが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
)
、この方法で動作します
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
のようになります。 item
で渡されたフォーマットされていない文字列の問題の影響を受けやすくなりますが、表示される最初の方法では何百ものクエリを実行するよりも高速になる可能性があります。質問のように文字列操作でこれを行うには
は注意してください願いOPの試行または受け入れられた回答のいずれも、真のパラメータ化されたSQLクエリーではない。 @Benjaminはより良い試みですが、他のものは単純に動的SQL文字列を連結しています。 – Parfait