使用R和ORDBC在数据库的单个表上插入数据帧

时间:2014-04-03 15:42:27

标签: mysql sql r rodbc

如何将完整的数据帧插入到单个mysql数据库表中

这是我的表

CREATE TABLE `data` (
`iddata` int(11) NOT NULL,
`x` varchar(45) DEFAULT NULL,
`y` varchar(45) DEFAULT NULL,
 PRIMARY KEY (`iddata`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

这是我的R代码:

file <- paste("C:\\Users\\zakaria\\Documents\\RDMZ\\test_rr.csv")
table <- read.table(file,sep=",",header=T)
channel <-odbcConnect(dsn="RSQL",uid="root",pwd="toor")
x <-table[,1]
y<-table[,2]



data<-sqlQuery(channel,paste("INSERT INTO 'data'.'dbwin'('x','y') VALUES (", x,", ", y, ");"))
sqlQuery(channel,data)

我有这个错误

[1] "42000 1064 [MySQL][ODBC 5.2(w) Driver][mysqld-5.6.17]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '42000 1064 [MySQL][ODBC 5.2(w) Driver][mysqld-5.6.17]You have an error in your S' at line 1"                   
[2] "[RODBC] ERROR: Could not SQLExecDirect '42000 1064 [MySQL][ODBC 5.2(w) Driver][mysqld-5.6.17]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''data'.'dbwin'('x','y') VALUES ( 0.708007801949862 ,  84 )' at line 1'"

谢谢你的帮助

1 个答案:

答案 0 :(得分:1)

执行此操作的最佳方法是使用@joran的建议:使用专为此设计的sqlSave(...)

您的代码无法正常工作有几个原因。一个问题是您将xy定义为varchar,但是您没有引用sql中的字符串。

x<-"A"
y<-"B"
sql <- paste("INSERT INTO 'data'.'dbwin'('x','y') VALUES (", x,", ", y, ");")
cat(sql)
# INSERT INTO 'data'.'dbwin'('x','y') VALUES ( A ,  B );

相反,请使用此:

sql <- paste0("INSERT INTO 'data'.'dbwin'('x','y') VALUES (\"", x,"\", \"", y, "\");")
cat(sql)
# INSERT INTO 'data'.'dbwin'('x','y') VALUES ("A", "B");

第二个是您不需要在sql中包含数据库名称,因为该信息嵌入在连接中。相反,使用类似的东西:

sql <- "INSERT INTO data (x,y) values (\"A\",\"B\")"

最后,最重要的是,这种形式的INSERT将一行添加到数据库表中,因此您不能将向量用于x和y(正如您的代码所做的那样)。这是一个解决方法:

## not tested
apply(table[,1:2], 1, function(values) {
  x    <- values[1]
  y    <- values[2]
  sql  <- paste0("INSERT INTO data (x,y) VALUES (\"", x,"\", \"", y, "\");")
  data <-sqlQuery(channel,sql)
  sqlQuery(channel,data)
})

这将(应该......)为table的每一行执行sql INSERT。它可能比sqlSave(...)慢。

最后,您不需要两次拨打sqlQuery(...)