是否可以使用RODBC軟件包對MS-SQL Server(2000,2005,2008)執行批量插入?使用RODBC的MS-SQL批量插入
我知道我可以使用freebcp來做到這一點,但我很好奇RODBC軟件包是否實現了Microsoft SQL API的這一部分,如果不是,實現它將會有多困難。
是否可以使用RODBC軟件包對MS-SQL Server(2000,2005,2008)執行批量插入?使用RODBC的MS-SQL批量插入
我知道我可以使用freebcp來做到這一點,但我很好奇RODBC軟件包是否實現了Microsoft SQL API的這一部分,如果不是,實現它將會有多困難。
您可能正在尋找?sqlSave
,當您設置Fast=True
時,它使用參數INSERT INTO
查詢(在一個操作中發生)。
現在你可以使用dbBulkCopy
從新rsqlserver包:
一個典型的例子:
dbBulkCopy
到讀取fil並使用MS Sql服務器的內部工具bcp
插入它。這假設你的表在數據庫中已經創建:
dat <- matrix(round(rnorm(nrow*ncol),nrow,ncol)
id.file = "temp_file.csv"
write.csv(dat,file=id.file,row.names=FALSE)
dbBulkCopy(conn,'NEW_BP_TABLE',value=id.file)
爲什麼rsqlserver不在cran上? – jangorecki 2014-02-06 16:56:16
@MusX因爲它正在開發中(特別是文檔和測試部分),它使用不在CRAN上的'rClr'軟件包。但是我們鼓勵您從GITHUB使用它,並會對任何反饋感到滿意。 – agstudy 2014-02-06 17:00:30
從一切我能找到,對於批量插入到MySQL並沒有什麼NO的解決方案,SSIS的工作這是爲什麼在購買Revolution R Analytics後,微軟將在SQL Server 2016中包含數據庫內分析功能。
我試着評論上一個答案,但沒有聲望去做。
的rsqlserver
包需要與rClr
運行和既不那些包都表現良好的,特別是因爲rsqlserver
的INSERT功能具有差的數據類型的處理。所以如果你使用它,你將不知道你在SQL表中看到什麼,因爲你的data.frame中的許多信息都將被轉換。
考慮到RODBC
包已經有15年了,我很失望,沒有人創造了一個批量插入功能...
重要的一點在rsqlserver上,但對於我們中的很多人來說,我們不需要'看'數據(從R的角度來看)。如果它已經在R中建模並進行了整形和處理,我們只需要將結果返回到數據庫中,並且R不會將數據類型轉換爲數據庫中的數據(只要它們合理並且可以被其他系統讀取) – Joe 2016-10-26 20:02:36
我們n2khelper
包可以使用bcp
(bulkcopy)可用時。如果不可用,它將回退到多個INSERT語句。
你可以找到https://github.com/INBO-Natura2000/n2khelper
包帶devtools::install_git("INBO-Natura2000/n2khelper")
安裝它,並尋找odbc_insert()
功能。
查看新的odbc
和DBI
包。 DBI::dbWriteTable
每秒寫入大約20,000條記錄......比行插入的速度快得多RODBC::sqlSave()
我們使用此函數來插入批量表。它使用RODBC包和它的連接。
dbhandle <- odbcDriverConnect('driver={SQL Server};server=server...')
sqlInsertBulk <- function(data, table, dbhandle,chunksize = 1000)
{
stopifnot(chunksize <= 1000)
nrow_initial<-sqlQuery(dbhandle,paste("SELECT COUNT (1) FROM ",table))
#If data includes Inf value, stop function.
numericCols <- names(data)[sapply(data, is.numeric)]
if (length(numericCols != 0)) {
if(sum(unlist(data[,lapply(.SD, function(x) any(x == Inf)),.SDcols = numericCols]),na.rm=T)>0){
stop("Data includes Inf value.")
}
}
chunknumber <- ceiling(nrow(data)/chunksize)
qstart <- paste("INSERT INTO ", table ," (",paste(colnames(data),collapse = ", "), ") VALUES")
for(chunki in 1:chunknumber)
{
chunkstart <- 1 + chunksize * (chunki - 1)
chunkend <- min(nrow(data), chunki * chunksize)
chunkdata <- data[chunkstart:chunkend]
valuestring <- vector(mode="character", length=chunkend - chunkstart + 1)
for(i in 1:nrow(chunkdata)){
valuestring[i] <- paste("(", paste(sapply(chunkdata[i], function(input){
if(!class(input) %in% c("numeric", "integer")) {
input<-paste0("'", input, "'")
}
if(is.na(input))
{
input<-"NULL"
}
return (input)
}), collapse=", "), ")")
}
qend <- paste(valuestring, collapse = ", ")
q <- paste(qstart, qend)
print(paste("Chunk", chunki, "is in process."))
sqlQuery(dbhandle,q)
print(paste("Chunk", chunki, "is uploaded."))
}
nrow_final <- sqlQuery(dbhandle,paste("SELECT COUNT (1) FROM ",table))
if(nrow_final-nrow_initial==nrow(data)) {
print(paste("All ",nrow(data)," data is uploaded."))
} else {
print(paste0("Warning!!! Only ",nrow_final-nrow_initial, " out of ",nrow(data), " are uploded."))
}
}
我不喜歡看不出這是如何進行批量上傳的。是不是隻是創建一個'INSERT INTO ...'查詢並通過'sqlQuery'發送它?所以它仍然會一次發送一行,即使R將它們作爲塊處理。 – 2017-12-05 04:55:16
@PeterEllis當然,它創建了INSERT INTO語句,但在該語句中有1000個(塊)行值。 因此,它的工作原理(數據)/大塊時間。假設我們有一個數據包含50k行。它向數據庫發送50個查詢而不是50000個查詢。所以速度顯着增加。 – Sab 2017-12-05 07:23:40
使用RODBC,最快的插入,我們已經能夠創建(260萬行的插入)如下所示(在讀僞代碼):
ourDataFrame <- sqlQuery(OurConnection, "SELECT myDataThing1, myDataThing2
FROM myData")
ourDF <- doStuff(ourDataFrame)
write.csv(ourDF,ourFile)
sqlQuery(OurConnection, "CREATE TABLE myTable (la [La], laLa [LaLa]);
BULK INSERT myTable FROM 'ourFile'
WITH YOURPARAMS=yourParams;")
如果你正在運行此從服務器之間,您需要一個R服務器可以寫入的網絡驅動器(例如,一個具有寫入數據庫權限的服務器使用Rscript來生成代碼),並且SQL Server可以讀取。
那麼,sqlSave會做多個INSERT。我想要一個BULK INSERT這是一個單獨的事務。 – ephpostfacto 2009-11-06 21:42:31
does fast = true不是作爲單個事務處理嗎? – Tyler 2009-11-09 23:40:59
from rodbc docs:「logical。If false,write data to a row at a time。If true,use an parametrized INSERT INTO or UPDATE query to write all the data in one operation。」但是它似乎沒有有什麼區別(在我的情況下寫入Netezza時) – Joe 2016-10-26 20:27:52