使用 SQL 循环插入而不删除空格
Loop with SQL insert not removing spaces
我有一种情况,我创建了一个循环来进行多次插入。但是,white space 在进行 SQL 语句时出错。示例如下:
下面的代码有效
query <- "INSERT INTO TBPPRODU (TBPCODIGO,PROCODIGO) VALUES (30084,'LD1268')"
dbSendQuery(con,query)
这行不通
prod <- data.frame(PROCODIGO=c("LD1268","LD1269","LD1270")
x <- data.frame(PROCODIGO=NA)
for (i in 1:nrow(prod)) {
x[i,] <- prod[i,]
query <- paste("INSERT INTO TBPPRODU (TBPCODIGO,PROCODIGO) VALUES (30084,'",x[i,"PROCODIGO"],"')",collapse = "")
dbSendQuery(con,query)
}
## the error output says there is white space before ' LD1268'
Error: nanodbc/nanodbc.cpp:1655: 23000: [ODBC Firebird Driver][Firebird]violation of FOREIGN KEY constraint "PRODU_TBPPRODU" on table "TBPPRODU"
Foreign key reference target does not exist
Problematic key value is ("PROCODIGO" = ' LD1268')
我已经尝试 trim 但效果不佳
query <- paste("INSERT INTO TBPPRODU (TBPCODIGO,PROCODIGO) VALUES (30084,'",x[trimws(i),"PROCODIGO"],"')",collapse = "")
我做错了什么?
这种方法有几个问题。
使用dbSendQuery(con, "INSERT INTO ...")
一次插入一行数据。首先创建 data.frame
,然后 dbWriteTable
它:
prod <- data.frame(PROCODIGO=c("LD1268","LD1269","LD1270"), TBPCODIGO=30084L)
dbAppendTable(con, "TBPPRODU", prod)
我认为应该更加小心地将 数据 制作成查询。 SQL injection can be both malicious (e.g., XKCD's Exploits of a Mom 又名“Little Bobby Tables”),这完全是偶然的。应该 never paste
“数据”到查询字符串中。选项:
- 参数化查询,见https://db.rstudio.com/best-practices/run-queries-safely/#parameterized-queries
glue::glue_sql
,优于 paste
,因为它采取措施确保数据正确转义。
即使您想使用 paste
,也要意识到它是在使用默认的 sep=" "
参数添加空格。
paste("VALUES (30084,'", "hello", "')")
# [1] "VALUES (30084,' hello ')" # not right
paste0("VALUES (30084,'", "hello", "')")
# [1] "VALUES (30084,'hello')"
paste("VALUES (30084,'", "hello", "')", sep = "") # equivalent to paste0
# [1] "VALUES (30084,'hello')"
我有一种情况,我创建了一个循环来进行多次插入。但是,white space 在进行 SQL 语句时出错。示例如下:
下面的代码有效
query <- "INSERT INTO TBPPRODU (TBPCODIGO,PROCODIGO) VALUES (30084,'LD1268')"
dbSendQuery(con,query)
这行不通
prod <- data.frame(PROCODIGO=c("LD1268","LD1269","LD1270")
x <- data.frame(PROCODIGO=NA)
for (i in 1:nrow(prod)) {
x[i,] <- prod[i,]
query <- paste("INSERT INTO TBPPRODU (TBPCODIGO,PROCODIGO) VALUES (30084,'",x[i,"PROCODIGO"],"')",collapse = "")
dbSendQuery(con,query)
}
## the error output says there is white space before ' LD1268'
Error: nanodbc/nanodbc.cpp:1655: 23000: [ODBC Firebird Driver][Firebird]violation of FOREIGN KEY constraint "PRODU_TBPPRODU" on table "TBPPRODU"
Foreign key reference target does not exist
Problematic key value is ("PROCODIGO" = ' LD1268')
我已经尝试 trim 但效果不佳
query <- paste("INSERT INTO TBPPRODU (TBPCODIGO,PROCODIGO) VALUES (30084,'",x[trimws(i),"PROCODIGO"],"')",collapse = "")
我做错了什么?
这种方法有几个问题。
使用
dbSendQuery(con, "INSERT INTO ...")
一次插入一行数据。首先创建data.frame
,然后dbWriteTable
它:prod <- data.frame(PROCODIGO=c("LD1268","LD1269","LD1270"), TBPCODIGO=30084L) dbAppendTable(con, "TBPPRODU", prod)
我认为应该更加小心地将 数据 制作成查询。 SQL injection can be both malicious (e.g., XKCD's Exploits of a Mom 又名“Little Bobby Tables”),这完全是偶然的。应该 never
paste
“数据”到查询字符串中。选项:- 参数化查询,见https://db.rstudio.com/best-practices/run-queries-safely/#parameterized-queries
glue::glue_sql
,优于paste
,因为它采取措施确保数据正确转义。
即使您想使用
paste
,也要意识到它是在使用默认的sep=" "
参数添加空格。paste("VALUES (30084,'", "hello", "')") # [1] "VALUES (30084,' hello ')" # not right paste0("VALUES (30084,'", "hello", "')") # [1] "VALUES (30084,'hello')" paste("VALUES (30084,'", "hello", "')", sep = "") # equivalent to paste0 # [1] "VALUES (30084,'hello')"