Распечатать 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 ответов
Я оформлю свой комментарий в ответ.
"Связывание" не изменяет запрос, оно просто "дополняет" запрос объектами, которые обрабатываются исключительно как данные, а код смешивается с кодом.
Последнее смешение может быть проблематичным по нескольким причинам:
Злонамеренный код, внедряющий "SQL-инъекцию" ( https://xkcd.com/327/ и объяснение вики). Короче говоря, он использует преимущество закрытия строки или литерала в кавычках и непосредственного выполнения кода SQL, возможно, для удаления или изменения данных, возможно, для извлечения данных.
Достаточно невинно, если "данные", которые вы добавляете в запрос, содержат кавычки, которые не экранированы должным образом, вы можете непреднамеренно выполнить собственную инъекцию SQL, хотя, возможно, с меньшей вероятностью будете делать "плохие вещи", как это сделал бы № 1.
Оптимизация кода 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)