2012-09-01 23 views
0

我正在編寫一個腳本,它從FTP服務器下載一串.csv文件,然後將每個.csv文件放入MySQL數據庫中作爲自己的表。當表名超過18個字符時,sqlSave失敗

我使用RCurl從FTP下載.csv,並將所有.csv放在我的工作目錄中。要從每個.csv創建表,我使用RODBC包中的sqlSave函數,其中表名與.csv的名稱相同。只要.csv名稱少於18個字符,這種方式就可以正常工作,但當它更大時,它就會失敗。而通過「失敗」,我的意思是R崩潰。爲了追蹤這個bug,我在sqlSave上調用了debug。

我發現sqlSave調用至少有兩個函數會導致R崩潰。第一個是RODBC ::: odbcTableExists,這是一個不可見的函數。下面是函數的代碼:

RODBC:::odbcTableExists 
function (channel, tablename, abort = TRUE, forQuery = TRUE, 
    allowDot = attr(channel, "interpretDot")) 
{ 
    if (!odbcValidChannel(channel)) 
     stop("first argument is not an open RODBC channel") 
    if (length(tablename) != 1) 
     stop(sQuote(tablename), " should be a name") 
    tablename <- as.character(tablename) 
    switch(attr(channel, "case"), nochange = { 
    }, toupper = tablename <- toupper(tablename), tolower = tablename <- tolower(tablename)) 
    isExcel <- odbcGetInfo(channel)[1L] == "EXCEL" 
    hasDot <- grepl(".", tablename, fixed = TRUE) 
    if (allowDot && hasDot) { 
     parts <- strsplit(tablename, ".", fixed = TRUE)[[1]] 
     if (length(parts) > 2) 
      ans <- FALSE 
     else { 
      res <- if (attr(channel, "isMySQL")) 
       sqlTables(channel, catalog = parts[1], tableName = parts[2]) 
      else sqlTables(channel, schema = parts[1], tableName = parts[2]) 
      ans <- is.data.frame(res) && nrow(res) > 0 
     } 
    } 
    else if (!isExcel) { 
     res <- sqlTables(channel, tableName = tablename) 
     ans <- is.data.frame(res) && nrow(res) > 0 
    } 
    else { 
     res <- sqlTables(channel) 
     tables <- stables <- if (is.data.frame(res)) 
      res[, 3] 
     else "" 
     if (isExcel) { 
      tables <- sub("^'(.*)'$", "\\1", tables) 
      tables <- unique(c(tables, sub("\\$$", "", tables))) 
     } 
     ans <- tablename %in% tables 
    } 
    if (abort && !ans) 
     stop(sQuote(tablename), ": table not found on channel") 
    enc <- attr(channel, "encoding") 
    if (nchar(enc)) 
     tablename <- iconv(tablename, to = enc) 
    if (ans && isExcel) { 
     dbname <- if (tablename %in% stables) 
      tablename 
     else paste(tablename, "$", sep = "") 
     if (forQuery) 
      paste("[", dbname, "]", sep = "") 
     else dbname 
    } 
    else if (ans) { 
     if (forQuery && !hasDot) 
      quoteTabNames(channel, tablename) 
     else tablename 
    } 
    else character(0L) 
} 

這這裏時失敗表名超過18個字符的長度:

res <- sqlTables(channel, tablename) 

res <- sqlTables(channel, tableName = tablename) 

我已經通過這個改變來固定它

然後,我使用assignInNamepace通過此代碼更改重新分配名稱空間中具有相同名稱的函數(odbcTableExists)。

RODBC ::: odbcTableExists不再導致問題。但是,從sqlSave()內調用sqlwrite時,R仍然崩潰。我調用sqlwrite調試,並發現RODBC ::: odbcColumns(另一個不可見的函數)會導致表名太長時崩潰。不幸的是,我不知道如何更改RODBC ::: odbcColumns以避免像我以前那樣的錯誤。

我,使用R 2.15.1和平臺是:x86_64的-PC-ming32/64(64位)。我還應該注意到,我想的是工作電腦上運行,但如果我在我的個人計算機上運行完全相同的代碼,R不會崩潰(無錯誤)。工作電腦運行Windows 7專業版,而我的家用電腦則運行R 2.14.1版本的Windows 7家庭高級版。

回答

0

我愛這個技巧(我也有Windows 7專業版在r 2.15.1在工作),並且它不會崩潰了,但我取代了系,用assignInNamespace後,它會導致另一個問題;也由於某種原因,我曾與RODBC ::: odbcValidChannel和quoteTabNames與RODBC ::: quoteTabNames

更換odbcValidChannel但是,當我使用sqlSave,我得到了以下錯誤:

錯誤odbcUpdate(通道,查詢,mydata,coldata [m,],test = test,: 沒有參數,所以沒有更新

我什至沒有在代碼中的任何地方使用odbcUpdate,並且RODBC ::: sqlSave沒有odbcUpdate在裏面打電話

有什麼想法?

謝謝你, -Alex

相關問題