2012-09-01 21 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

相关问题