2015-09-14 55 views
2

我幾乎沒有SQL語句的使用經驗,所以我對此問題的潛在無知表示歉意。但是,讓我們說我有有b1 b2 b3 b4的列字段的SQL表results,我有右輸出dat對應於這些數值看上去像:在SQL表中動態插入R輸出

print(dat) 
b1 b2 b3 b4 
7 8 7 1 

所以,我可以跑,看起來像一個SQL語句:

a<-paste("INSERT INTO `results` (`b1`,`b2`,`b3`,`b4`) VALUES ","(",dat$b1,",",dat$b2,",",dat$b3,",",dat$b4",")",";",sep="") 
for(i in(1:length(b))){ 
query(b[i]) 
} 

哪個工作正常;然而,這不是動態的,因爲dat(即R輸出)將不總是包含在results(即數據庫列字段)中找到的所有列值,儘管輸出永遠不會有列中找不到的列數據庫列字段(例如,在這種情況下dat將永遠不會有b5列)。我正在嘗試動態編寫代碼,以便我不必在代碼中寫出所有的dat列和results列名稱字段,並將dat寫入results,這樣無論順序如何,dat中的列都會進入相應的列列字段results,最後如果在dat中缺少列值,NA將進入results中的對應列字段。例如,如果dat看起來像:

print(dat) 
b4 b1 
7 8 

results會是什麼樣子:

b1 b2 b3 b4 
8 NA NA 7 

謝謝!

+0

如果dat不包含列,則返回的值將爲NULL。例如dat $ b2和dat $ b3將返回NULL,這可以用來代替NA嗎? –

+0

是NULL完全正常。 – costebk08

+0

然後您的查詢應適用於所有情況。你沒試過嗎? –

回答

2

您可以在一個非常簡單的方式將其參數化(並且你可以用下面的功能整合到一個功能,使用更簡便):

dat <- mtcars 

inserts <- sprintf("INSERT INTO `%s` (%s) VALUES (%s);", 
     "results", 
     paste(sprintf("`%s`", colnames(dat)), collapse=", "), 
     sapply(1:nrow(dat), function(i) { 
      paste(sprintf("`%s`", unlist(dat[i,], use.names=FALSE)) , collapse=", ") 
     })) 

head(inserts) 
## [1] "INSERT INTO `results` (`mpg`, `cyl`, `disp`, `hp`, `drat`, `wt`, `qsec`, `vs`, `am`, `gear`, `carb`) VALUES (`21`, `6`, `160`, `110`, `3.9`, `2.62`, `16.46`, `0`, `1`, `4`, `4`);"  
## [2] "INSERT INTO `results` (`mpg`, `cyl`, `disp`, `hp`, `drat`, `wt`, `qsec`, `vs`, `am`, `gear`, `carb`) VALUES (`21`, `6`, `160`, `110`, `3.9`, `2.875`, `17.02`, `0`, `1`, `4`, `4`);" 
## [3] "INSERT INTO `results` (`mpg`, `cyl`, `disp`, `hp`, `drat`, `wt`, `qsec`, `vs`, `am`, `gear`, `carb`) VALUES (`22.8`, `4`, `108`, `93`, `3.85`, `2.32`, `18.61`, `1`, `1`, `4`, `1`);" 
## [4] "INSERT INTO `results` (`mpg`, `cyl`, `disp`, `hp`, `drat`, `wt`, `qsec`, `vs`, `am`, `gear`, `carb`) VALUES (`21.4`, `6`, `258`, `110`, `3.08`, `3.215`, `19.44`, `1`, `0`, `3`, `1`);" 
## [5] "INSERT INTO `results` (`mpg`, `cyl`, `disp`, `hp`, `drat`, `wt`, `qsec`, `vs`, `am`, `gear`, `carb`) VALUES (`18.7`, `8`, `360`, `175`, `3.15`, `3.44`, `17.02`, `0`, `0`, `3`, `2`);" 
## [6] "INSERT INTO `results` (`mpg`, `cyl`, `disp`, `hp`, `drat`, `wt`, `qsec`, `vs`, `am`, `gear`, `carb`) VALUES (`18.1`, `6`, `225`, `105`, `2.76`, `3.46`, `20.22`, `1`, `0`, `3`, `1`);" 
dat <- iris 

inserts <- sprintf("INSERT INTO `%s` (%s) VALUES (%s);", 
     "results", 
     paste(sprintf("`%s`", colnames(dat)), collapse=", "), 
     sapply(1:nrow(dat), function(i) { 
      paste(sprintf("`%s`", unlist(dat[i,], use.names=FALSE)) , collapse=", ") 
     })) 

head(inserts) 
## [1] "INSERT INTO `results` (`Sepal.Length`, `Sepal.Width`, `Petal.Length`, `Petal.Width`, `Species`) VALUES (`5.1`, `3.5`, `1.4`, `0.2`, `1`);" 
## [2] "INSERT INTO `results` (`Sepal.Length`, `Sepal.Width`, `Petal.Length`, `Petal.Width`, `Species`) VALUES (`4.9`, `3`, `1.4`, `0.2`, `1`);" 
## [3] "INSERT INTO `results` (`Sepal.Length`, `Sepal.Width`, `Petal.Length`, `Petal.Width`, `Species`) VALUES (`4.7`, `3.2`, `1.3`, `0.2`, `1`);" 
## [4] "INSERT INTO `results` (`Sepal.Length`, `Sepal.Width`, `Petal.Length`, `Petal.Width`, `Species`) VALUES (`4.6`, `3.1`, `1.5`, `0.2`, `1`);" 
## [5] "INSERT INTO `results` (`Sepal.Length`, `Sepal.Width`, `Petal.Length`, `Petal.Width`, `Species`) VALUES (`5`, `3.6`, `1.4`, `0.2`, `1`);" 
## [6] "INSERT INTO `results` (`Sepal.Length`, `Sepal.Width`, `Petal.Length`, `Petal.Width`, `Species`) VALUES (`5.4`, `3.9`, `1.7`, `0.4`, `1`);" 

set.seed(1492) 
dat <- data.frame(b1=sample(10, 10), 
        b2=sample(10, 10), 
        b3=sample(10, 10), 
        b4=sample(10, 10)) 

inserts <- sprintf("INSERT INTO `%s` (%s) VALUES (%s);", 
     "results", 
     paste(sprintf("`%s`", colnames(dat)), collapse=", "), 
     sapply(1:nrow(dat), function(i) { 
      paste(sprintf("`%s`", unlist(dat[i,], use.names=FALSE)) , collapse=", ") 
     })) 

head(inserts) 
## [1] "INSERT INTO `results` (`b1`, `b2`, `b3`, `b4`) VALUES (`3`, `7`, `7`, `2`);" 
## [2] "INSERT INTO `results` (`b1`, `b2`, `b3`, `b4`) VALUES (`2`, `6`, `4`, `9`);" 
## [3] "INSERT INTO `results` (`b1`, `b2`, `b3`, `b4`) VALUES (`9`, `2`, `2`, `7`);" 
## [4] "INSERT INTO `results` (`b1`, `b2`, `b3`, `b4`) VALUES (`1`, `4`, `5`, `10`);" 
## [5] "INSERT INTO `results` (`b1`, `b2`, `b3`, `b4`) VALUES (`7`, `10`, `1`, `6`);" 
## [6] "INSERT INTO `results` (`b1`, `b2`, `b3`, `b4`) VALUES (`6`, `9`, `10`, `4`);" 

但是,如果我們更瞭解您真正想要解決的問題,可能會有更多最佳方式將這些數據放回到數據庫中。

+0

這看起來像一個很好的解決方案,但我無法完成它的工作。當我查詢'inserts'時出現以下錯誤:'.local(conn,statement,...)中的錯誤:無法運行語句:'字段列表'中的未知列'-0.0366528160'該值來自第一個列,所以它看起來像它認爲那是列名。有什麼想法嗎?謝謝 – costebk08

+0

我不知道你正在使用什麼數據庫,模式是如何設置的或者它接受的SQL語法。我只是在處理你提供的例子。 – hrbrmstr

+0

好的,謝謝。我將研究具體的語法。 – costebk08

2

不知道如果你有一個龐大的數據庫,但是一個簡單的解決方法就是將數據集讀入R,追加一個數據集(例如,使用dplyr::bind_rows),然後再把整個事情寫出來。

library(RMySQL) 
library(dplyr) 

con = dbConnect(RMySQL::MySQL(), dbname = "test") 
con %>% 
    dbReadTable("results") %>% 
    bind_rows(dat) %>% 
    dbWriteTable(con, "results", . , overwrite = TRUE) 
dbDisconnect(con) 

或者

con %>% dbWriteTable("results", dat, append = TRUE) 

要創建表,

con %>% dbWriteTable("results", dat) 
+0

那麼究竟如何這看起來會嗎? – costebk08

+0

查看上面的編輯 – bramtayl

+0

是的我可能不想每次都將整個數據庫讀入R,我無法使這個解決方案工作。我假設這是因爲我目前沒有數據庫表中的數據,並且它看起來像這個解決方案假定數據已經存在那裏。 – costebk08