Распечатать SQL-оператор, созданный DBI::dbBind

Я хочу напечатать синтаксис sql, созданный с помощью DBI::dbBind при создании безопасного параметризованного запроса:

conn <- #create connection 
stmt <- "select * from dbo.mytable where mycolumn = ?"
params = list("myvalue")

query <- DBI::dbSendQuery(conn, stmt)
DBI::dbBind(query, params) # how print created sql syntax?

в последней строке создается синтаксис sql. Как посмотреть это?

0 ответов

Я оформлю свой комментарий в ответ.

"Связывание" не изменяет запрос, оно просто "дополняет" запрос объектами, которые обрабатываются исключительно как данные, а код смешивается с кодом.

Последнее смешение может быть проблематичным по нескольким причинам:

  1. Злонамеренный код, внедряющий "SQL-инъекцию" ( https://xkcd.com/327/ и объяснение вики). Короче говоря, он использует преимущество закрытия строки или литерала в кавычках и непосредственного выполнения кода SQL, возможно, для удаления или изменения данных, возможно, для извлечения данных.

  2. Достаточно невинно, если "данные", которые вы добавляете в запрос, содержат кавычки, которые не экранированы должным образом, вы можете непреднамеренно выполнить собственную инъекцию SQL, хотя, возможно, с меньшей вероятностью будете делать "плохие вещи", как это сделал бы № 1.

  3. Оптимизация кода SQL. Большинство СУБД анализируют и оптимизируют запрос SQL, чтобы он работал лучше, использовали преимущества ключей и т. Д. Они часто запоминают запросы, поэтому повторный запрос не нужно повторно анализировать, что экономит время. Если вы смешаете данные / параметры с необработанным текстом запроса SQL, то, когда вы измените одну вещь об этом (даже одну цифру в параметре), СУБД, вероятно, потребуется повторно проанализировать запрос. Неэффективное.

Существуют функции, которые облегчают экранирование или цитирование литералов и строк, и если вы чувствуете, что должны вставить литералы в свой SQL-запрос, тогда я призываю вас использовать их. К ним относятся (но не ограничиваются) DBI::dbQuoteString, DBI::dbQuoteLiteral, а также DBI::dbQuoteIdentifier,

Еще одна такая функция glue::glue_sql, который обрабатывает правильные кавычки / экранирование литералов и идентификаторов, чтобы "сделать построение операторов SQL безопасным и легким" (цитируется из репозитория github). Это "простая" интерполяция строк, поэтому, хотя она должна отлично защитить вас от #1 и #2 выше, она не обязательно разрешает / поощряет # 3.

(Требуется всего одна неправильная цитата, чтобы напомнить вам, где и где используется ваша конкретная СУБД.)

Для записи, связывание довольно просто, как предусмотрено в его документации:

iris_result <- dbSendQuery(con, "SELECT * FROM iris WHERE [Petal.Width] > ?")
dbBind(iris_result, list(2.3))
results <- dbFetch(iris_result)

Если вы хотите, вы можете повторно использовать тот жеres (по крайней мере, в некоторых СУБД, не проверенных на всех), как в

# same iris_result as above
dbBind(iris_result, list(2.5))
dbFetch(iris_result)
dbBind(iris_result, list(3))
dbFetch(iris_result)
dbBind(iris_result, list(3.2))
dbFetch(iris_result)

Столько раз, сколько вам нужно, в конечном итоге заканчивая

DBI::dbClearResult(iris_result)
Другие вопросы по тегам