SQL 數據庫通常對標識符和字符串具有自定義引用語法,這使得編寫 SQL 查詢容易出錯且繁瑣。 glue_sql()
和 glue_data_sql()
類似於處理 SQL 引用的 glue()
和 glue_data()
。 glue_sql_collapse()
可用於折疊DBI::SQL()
對象。
用法
glue_sql(..., .con, .envir = parent.frame(), .na = DBI::SQL("NULL"))
glue_data_sql(.x, ..., .con, .envir = parent.frame(), .na = DBI::SQL("NULL"))
參數
- ...
-
[
expressions
]
未命名的參數被視為要格式化的表達式字符串。多個輸入在格式化之前連接在一起。命名參數被視為可用於替換的臨時變量。 - .con
-
[
DBIConnection
]:從DBI::dbConnect()
獲取的DBI連接對象。 - .envir
-
[
environment
:parent.frame()
]
計算每個表達式的環境。表達式從左到右計算。如果.x
是一個環境,表達式在該環境中求值並且.envir
被忽略。如果NULL
通過了,就相當於emptyenv()
. - .na
-
[
character(1)
:‘不適用’]
要替換的值NA
值與.如果NULL
缺失值被傳播,即NA
結果會導致NA
輸出。否則該值將被替換為.na
. - .x
-
[
listish
]
用於查找值的環境、列表或 DataFrame 。
值
具有給定查詢的 DBI::SQL()
對象。
細節
它們會自動引用字符結果,如果粘合表達式被反引號“`
”包圍,則引用標識符,並且不引用非字符(例如數字)。如果數字數據存儲在字符列(應加引號)中,則將數據作為字符傳遞給glue_sql()
。
如果需要給定值,使用 DBI::SQL()
返回結果將抑製引用。
注意 parameterized queries 通常是在查詢中傳遞用戶定義值的最安全、最有效的方法,但並非每個數據庫驅動程序都支持它們。
如果將 *
放在粘合表達式的末尾,則值將用逗號折疊。例如,這對於 SQL IN Operator 很有用。
也可以看看
glue_sql_collapse()
折疊 DBI::SQL()
對象。
例子
con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
iris2 <- iris
colnames(iris2) <- gsub("[.]", "_", tolower(colnames(iris)))
DBI::dbWriteTable(con, "iris", iris2)
var <- "sepal_width"
tbl <- "iris"
num <- 2
val <- "setosa"
glue_sql("
SELECT {`var`}
FROM {`tbl`}
WHERE {`tbl`}.sepal_length > {num}
AND {`tbl`}.species = {val}
", .con = con)
#> <SQL> SELECT `sepal_width`
#> FROM `iris`
#> WHERE `iris`.sepal_length > 2
#> AND `iris`.species = 'setosa'
# If sepal_length is store on the database as a character explicitly convert
# the data to character to quote appropriately.
glue_sql("
SELECT {`var`}
FROM {`tbl`}
WHERE {`tbl`}.sepal_length > {as.character(num)}
AND {`tbl`}.species = {val}
", .con = con)
#> <SQL> SELECT `sepal_width`
#> FROM `iris`
#> WHERE `iris`.sepal_length > '2'
#> AND `iris`.species = 'setosa'
# `glue_sql()` can be used in conjuction with parameterized queries using
# `DBI::dbBind()` to provide protection for SQL Injection attacks
sql <- glue_sql("
SELECT {`var`}
FROM {`tbl`}
WHERE {`tbl`}.sepal_length > ?
", .con = con)
query <- DBI::dbSendQuery(con, sql)
DBI::dbBind(query, list(num))
DBI::dbFetch(query, n = 4)
#> sepal_width
#> 1 3.5
#> 2 3.0
#> 3 3.2
#> 4 3.1
DBI::dbClearResult(query)
# `glue_sql()` can be used to build up more complex queries with
# interchangeable sub queries. It returns `DBI::SQL()` objects which are
# properly protected from quoting.
sub_query <- glue_sql("
SELECT *
FROM {`tbl`}
", .con = con)
glue_sql("
SELECT s.{`var`}
FROM ({sub_query}) AS s
", .con = con)
#> <SQL> SELECT s.`sepal_width`
#> FROM (SELECT *
#> FROM `iris`) AS s
# If you want to input multiple values for use in SQL IN statements put `*`
# at the end of the value and the values will be collapsed and quoted appropriately.
glue_sql("SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})",
vals = 1, .con = con)
#> <SQL> SELECT * FROM `iris` WHERE sepal_length IN (1)
glue_sql("SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})",
vals = 1:5, .con = con)
#> <SQL> SELECT * FROM `iris` WHERE sepal_length IN (1, 2, 3, 4, 5)
glue_sql("SELECT * FROM {`tbl`} WHERE species IN ({vals*})",
vals = "setosa", .con = con)
#> <SQL> SELECT * FROM `iris` WHERE species IN ('setosa')
glue_sql("SELECT * FROM {`tbl`} WHERE species IN ({vals*})",
vals = c("setosa", "versicolor"), .con = con)
#> <SQL> SELECT * FROM `iris` WHERE species IN ('setosa', 'versicolor')
# If you need to reference variables from multiple tables use `DBI::Id()`.
# Here we create a new table of nicknames, join the two tables together and
# select columns from both tables. Using `DBI::Id()` and the special
# `glue_sql()` syntax ensures all the table and column identifiers are quoted
# appropriately.
iris_db <- "iris"
nicknames_db <- "nicknames"
nicknames <- data.frame(
species = c("setosa", "versicolor", "virginica"),
nickname = c("Beachhead Iris", "Harlequin Blueflag", "Virginia Iris"),
stringsAsFactors = FALSE
)
DBI::dbWriteTable(con, nicknames_db, nicknames)
cols <- list(
DBI::Id(table = iris_db, column = "sepal_length"),
DBI::Id(table = iris_db, column = "sepal_width"),
DBI::Id(table = nicknames_db, column = "nickname")
)
iris_species <- DBI::Id(table = iris_db, column = "species")
nicknames_species <- DBI::Id(table = nicknames_db, column = "species")
query <- glue_sql("
SELECT {`cols`*}
FROM {`iris_db`}
JOIN {`nicknames_db`}
ON {`iris_species`}={`nicknames_species`}",
.con = con
)
query
#> <SQL> SELECT `iris`.`sepal_length`, `iris`.`sepal_width`, `nicknames`.`nickname`
#> FROM `iris`
#> JOIN `nicknames`
#> ON `iris`.`species`=`nicknames`.`species`
DBI::dbGetQuery(con, query, n = 5)
#> sepal_length sepal_width nickname
#> 1 5.1 3.5 Beachhead Iris
#> 2 4.9 3.0 Beachhead Iris
#> 3 4.7 3.2 Beachhead Iris
#> 4 4.6 3.1 Beachhead Iris
#> 5 5.0 3.6 Beachhead Iris
DBI::dbDisconnect(con)
相關用法
- R glue glue_safe 安全地插入字符串
- R glue glue_col 用顏色構造字符串
- R glue glue_collapse 折疊字符向量
- R glue glue 格式化並插入字符串
- R glue trim 修剪字符向量
- R glue quoting 引用運算符
- R SparkR glm用法及代碼示例
- R ggplot2 annotation_logticks 注釋:記錄刻度線
- R axisTicks 計算漂亮的軸刻度
- R googledrive drive_cp 複製雲端硬盤文件
- R legend 將圖例添加到繪圖中
- R googledrive drive_mime_type 查找 MIME 類型
- R ggplot2 vars 引用分麵變量
- R grid.curve 在位置之間繪製曲線
- R googledrive drive_reveal 添加新的雲端硬盤文件信息列
- R googledrive drive_rm 從雲端硬盤刪除文件
- R ggplot2 position_stack 將重疊的對象堆疊在一起
- R ggplot2 geom_qq 分位數-分位數圖
- R hcl HCL 顏色規格
- R legendGrob 構建一個圖例 Grob
- R quartzFonts 石英字體
- R ggplot2 geom_spoke 由位置、方向和距離參數化的線段
- R googlesheets4 sheet_rename 重命名(工作)表
- R googledrive expose 暴露對象
- R grid.draw 畫一個網格
注:本文由純淨天空篩選整理自Jim Hester等大神的英文原創作品 Interpolate strings with SQL escaping。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。