在 Mysql table RMySQL 中插入 NA 值
Insert NA values in Mysql table RMySQL
我试图在 mysql table 中插入一个数据框行,但我在字符和数字列中有 NA 值。我收到此错误: .local(conn, statement, ...) 错误:
无法 运行 语句:'field list'
中的未知列 'NA'
这是我的查询:
sql <- sprintf("insert into payment (amount,payment_type,date,customer_total,base_price, p2c_total, partner_total, pay_online, pay_at_lot,tax,first_name_on_card,last_name_on_card,address)
values (%f, %d, '%s',%f,%f,%f,%f,%f,%f,%f,'%s','%s','%s');",
payments[i,]$amount,payments[i,]$payment_type,payments[i,]$date, payments[i,]$customer_total,
payments[i,]$base_price, payments[i,]$p2c_total, payments[i,]$partner_total,
payments[i,]$pay_online,payments[i,]$pay_at_lot,payments[i,]$tax,
payments[i,]$first_name_on_card, payments[i,]$last_name_on_card, payments[i,]$address)
rs <- dbSendQuery(db, sql[i])
dbClearResult(rs)
这是 sql 代码:
insert into reservation (reservation_number, driver_name, number_passengers, checkin_datetime, checkout_datetime, days, reservation_date, reservation_email,id_reservation_status, id_payment, id_ship, id_facility, id_user) values ('j990j','CB', 4, '2020-01-12 10:00:00', '2020-01-19 10:30:00', 8, 'NA', 'cb@gmail.com',NA, 1, 2, 547, 6);
这是 mysql 错误:
#1054 - La columna 'NA' en field list es desconocida
MySQL版本:8.0.27
R 版本:4.03
RMySQL 包:0.10.22
将您的 NA
换成 'NA'
insert into reservation (reservation_number, driver_name, number_passengers, checkin_datetime, checkout_datetime, days, reservation_date, reservation_email,id_reservation_status, id_payment, id_ship, id_facility, id_user) values ('j990j','CB', 4, '2020-01-12 10:00:00', '2020-01-19 10:30:00', 8, 'NA', 'cb@gmail.com','NA', 1, 2, 547, 6);
三种方式来看待这个问题:
不要sprintf
/paste
数据到查询字符串中。除了 malicious SQL injection (e.g., XKCD's Exploits of a Mom aka "Little Bobby Tables") 的安全问题外,它还涉及格式错误的字符串或 Unicode-vs-ANSI 错误,即使它是一个数据分析师 运行 查询。
方便的是,有一个函数负责以更安全的方式将数据从 data.frame
插入 table:dbAppendTable
。你也许可以做到
dbAppendTable(db, "payment", payments[i,])
如果需要插入所有列,否则需要更详细的内容:
dbAppendTable(db, "payment", payments[i,c("amount", "payment_type", "date", "customer_total", "base_price", "p2c_total", "partner_total", "pay_online", "pay_at_lot", "tax", "first_name_on_card", "last_name_on_card", "address")])
如果您计划对超过 1 行执行此操作,那么 dbAppendTable
可以毫无问题地处理多行。
如果你真的想用你自己的 insert
语句一次做一行,那么我强烈建议你使用参数化查询,也许是这样的:
qry <- "insert into payment (amount,payment_type,date,customer_total,base_price, p2c_total, partner_total, pay_online, pay_at_lot,tax,first_name_on_card,last_name_on_card,address)
values (?, ?, ?,?,?,?,?,?,?,?,?,?,?);"
dbExecute(db, qry, params = payments[i, c("amount", "payment_type", ...)])
(这让我想起了......dbExecute
是一个很好的包装器,它确实 dbSendStatement
总是跟在 dbClearResult
之后。还有 dbGetQuery
这实际上是 dbSendQuery
总是后跟 dbClearResult
,返回数据。您不会从 table 返回行,所以无论如何第一个是首选。)
注意:此功能需要 up-to-date 驱动程序来访问数据库。如果您使用 RMySQL
那么就会有一个问题:该包多年来(截至目前)没有看到实质性更新,并且不支持参数化查询。我相信 RMariaDB
包与 MySQL 和 完全兼容,它支持参数化查询。
如果你真的必须手动执行此操作(真的,我强烈反对,太多次我认为我可以解决风险,但每次都被咬),那么 R 的 NA
翻译成 null
(没有引号!)。为此,您需要有条件地添加引号。类似于:
ifelse(is.na(payments[i,]$date), "null", sQuote(payments[i,]$date))
for each string-like 字段,并确保将格式中的 '%s'
更改为 %s
。几乎可以肯定有更好的方法可以自动执行此操作,这样您就不会输入一打或更多 ifelse
,但在我看来,这样做确实不值得。
(如果您依赖 sprintf("%s", ..)
的不同语义与 sQuote
的隐式 string-ification,那么您可能需要更多 elbow-grease。)
我试图在 mysql table 中插入一个数据框行,但我在字符和数字列中有 NA 值。我收到此错误: .local(conn, statement, ...) 错误: 无法 运行 语句:'field list'
中的未知列 'NA'这是我的查询:
sql <- sprintf("insert into payment (amount,payment_type,date,customer_total,base_price, p2c_total, partner_total, pay_online, pay_at_lot,tax,first_name_on_card,last_name_on_card,address)
values (%f, %d, '%s',%f,%f,%f,%f,%f,%f,%f,'%s','%s','%s');",
payments[i,]$amount,payments[i,]$payment_type,payments[i,]$date, payments[i,]$customer_total,
payments[i,]$base_price, payments[i,]$p2c_total, payments[i,]$partner_total,
payments[i,]$pay_online,payments[i,]$pay_at_lot,payments[i,]$tax,
payments[i,]$first_name_on_card, payments[i,]$last_name_on_card, payments[i,]$address)
rs <- dbSendQuery(db, sql[i])
dbClearResult(rs)
这是 sql 代码:
insert into reservation (reservation_number, driver_name, number_passengers, checkin_datetime, checkout_datetime, days, reservation_date, reservation_email,id_reservation_status, id_payment, id_ship, id_facility, id_user) values ('j990j','CB', 4, '2020-01-12 10:00:00', '2020-01-19 10:30:00', 8, 'NA', 'cb@gmail.com',NA, 1, 2, 547, 6);
这是 mysql 错误: #1054 - La columna 'NA' en field list es desconocida
MySQL版本:8.0.27
R 版本:4.03
RMySQL 包:0.10.22
将您的 NA
换成 'NA'
insert into reservation (reservation_number, driver_name, number_passengers, checkin_datetime, checkout_datetime, days, reservation_date, reservation_email,id_reservation_status, id_payment, id_ship, id_facility, id_user) values ('j990j','CB', 4, '2020-01-12 10:00:00', '2020-01-19 10:30:00', 8, 'NA', 'cb@gmail.com','NA', 1, 2, 547, 6);
三种方式来看待这个问题:
不要
sprintf
/paste
数据到查询字符串中。除了 malicious SQL injection (e.g., XKCD's Exploits of a Mom aka "Little Bobby Tables") 的安全问题外,它还涉及格式错误的字符串或 Unicode-vs-ANSI 错误,即使它是一个数据分析师 运行 查询。方便的是,有一个函数负责以更安全的方式将数据从
data.frame
插入 table:dbAppendTable
。你也许可以做到dbAppendTable(db, "payment", payments[i,])
如果需要插入所有列,否则需要更详细的内容:
dbAppendTable(db, "payment", payments[i,c("amount", "payment_type", "date", "customer_total", "base_price", "p2c_total", "partner_total", "pay_online", "pay_at_lot", "tax", "first_name_on_card", "last_name_on_card", "address")])
如果您计划对超过 1 行执行此操作,那么
dbAppendTable
可以毫无问题地处理多行。如果你真的想用你自己的
insert
语句一次做一行,那么我强烈建议你使用参数化查询,也许是这样的:qry <- "insert into payment (amount,payment_type,date,customer_total,base_price, p2c_total, partner_total, pay_online, pay_at_lot,tax,first_name_on_card,last_name_on_card,address) values (?, ?, ?,?,?,?,?,?,?,?,?,?,?);" dbExecute(db, qry, params = payments[i, c("amount", "payment_type", ...)])
(这让我想起了......
dbExecute
是一个很好的包装器,它确实dbSendStatement
总是跟在dbClearResult
之后。还有dbGetQuery
这实际上是dbSendQuery
总是后跟dbClearResult
,返回数据。您不会从 table 返回行,所以无论如何第一个是首选。)注意:此功能需要 up-to-date 驱动程序来访问数据库。如果您使用
RMySQL
那么就会有一个问题:该包多年来(截至目前)没有看到实质性更新,并且不支持参数化查询。我相信RMariaDB
包与 MySQL 和 完全兼容,它支持参数化查询。如果你真的必须手动执行此操作(真的,我强烈反对,太多次我认为我可以解决风险,但每次都被咬),那么 R 的
NA
翻译成null
(没有引号!)。为此,您需要有条件地添加引号。类似于:ifelse(is.na(payments[i,]$date), "null", sQuote(payments[i,]$date))
for each string-like 字段,并确保将格式中的
'%s'
更改为%s
。几乎可以肯定有更好的方法可以自动执行此操作,这样您就不会输入一打或更多ifelse
,但在我看来,这样做确实不值得。(如果您依赖
sprintf("%s", ..)
的不同语义与sQuote
的隐式 string-ification,那么您可能需要更多 elbow-grease。)