RODBC 不会从数据框中保存超过 8k 的 varchar/text
Posted
技术标签:
【中文标题】RODBC 不会从数据框中保存超过 8k 的 varchar/text【英文标题】:RODBC does not save greater than 8k varchar/text from a data frame 【发布时间】:2013-08-28 01:26:54 【问题描述】:我正在抓取网络数据,有些结果超过 8K 的文本。我的 MS SQL Server 2008 R2 中有一个字段是 varchar(max) 但 RODBC 只保存 8K 并截断其余部分。我使用 SS R2 中的 SQL Native Client 10 和 ODBC 11 设置了 DSN 连接。
sqlType 为字段标题返回 -1,表示 varchar(max)/text。
两个连接都会截断 8K 的文本。是否有解决方案/解决方法,或者我在 SQL Server 中是否限制为 8K?如果 R mysql 驱动程序将传递大量文本,我可以切换到 MySQL。我在 Win 7 x64 上使用 R 3.0.1 和 RODBC 1.3-6。
这里是一些复制问题的示例代码。
CREATE TABLE
[test](
[title] [varchar](max) NULL
) ON [PRIMARY]
library(RODBC)
ch <- odbcConnect("text", uid = "X", pwd = "X")
sqlTypeInfo(ch,"test")
testtext = data.frame("salasjflsjsf")
colnames(testtext) = "title"
## This works
sqlSave(ch,testtext,"test",append=TRUE, rownames=FALSE, colnames = FALSE, safer=FALSE, verbose = TRUE)
## text > 8K
testtext = data.frame(paste(rep("salasjflsjsf",5000),collapse=""))
colnames(testtext) = "title"
## use ODBC default type for title
sqlSave(ch,testtext,"test",append=TRUE, rownames=FALSE, colnames = FALSE, safer=FALSE, verbose = TRUE)
## this message from ODBC
## Query: INSERT INTO "test" ( "title" ) VALUES ( ? )
## Binding: 'title' DataType 12, ColSize 8000
## Parameters:
## no: 1: title salasjfl
## [*text removed*]
## lsjsfsalasjflsjsfsalasjflsjsfsalasjflsjsfsalasjflsjsfsalasjflsjsfsalasjflsjsf/***/
## Warning message:
## In odbcUpdate(channel, query, mydata, coldata[m, ], test = test, :
## character data 'salasjflsjsfsalasjflsjsfsalasjflsjsfsalasjfl
## try with varType set to text
sqlSave(ch,testtext,"test",append=TRUE, varType = "text",rownames=FALSE, colnames = FALSE, safer=FALSE, verbose = TRUE)
## try with varType set to varchar(MAX)
sqlSave(ch,testtext,"test",append=TRUE, varType = "varchar(max)",rownames=FALSE, colnames = FALSE, safer=FALSE, verbose = TRUE)
close(ch)
我将列类型更改为文本并刷新了 DSN 连接。正在提取文本类型,但现在出现错误消息:
chtest <-odbcConnect("test2", uid = "X", pwd = "X")
> sqlColumns(chtest,"test")
TABLE_CAT TABLE_SCHEM TABLE_NAME COLUMN_NAME DATA_TYPE TYPE_NAME COLUMN_SIZE BUFFER_LENGTH DECIMAL_DIGITS NUM_PREC_RADIX NULLABLE REMARKS
1 RSS dbo test title -1 text 2147483647 2147483647 NA NA 1 <NA>
COLUMN_DEF SQL_DATA_TYPE SQL_DATETIME_SUB CHAR_OCTET_LENGTH ORDINAL_POSITION IS_NULLABLE SS_IS_SPARSE SS_IS_COLUMN_SET SS_IS_COMPUTED
1 <NA> -1 NA 2147483647 1 YES 0 0 0
SS_IS_IDENTITY SS_UDT_CATALOG_NAME SS_UDT_SCHEMA_NAME SS_UDT_ASSEMBLY_TYPE_NAME SS_XML_SCHEMACOLLECTION_CATALOG_NAME
1 0 <NA> <NA> <NA> <NA>
SS_XML_SCHEMACOLLECTION_SCHEMA_NAME SS_XML_SCHEMACOLLECTION_NAME SS_DATA_TYPE
1 <NA> <NA> 35
> sqlSave(chtest,testtext,"test",append=TRUE, varType = "text",rownames=FALSE, colnames = FALSE, safer=FALSE, verbose = TRUE)
Query: INSERT INTO "test" ( "title" ) VALUES ( ? )
Binding: 'title' DataType -1, ColSize 2147483647
Error in odbcUpdate(channel, query, mydata, coldata[m, ], test = test, :
'Calloc' could not allocate memory (18446744071562067968 of 1 bytes)
In addition: Warning messages:
1: In odbcUpdate(channel, query, mydata, coldata[m, ], test = test, :
Reached total allocation of 6013Mb: see help(memory.size)
2: In odbcUpdate(channel, query, mydata, coldata[m, ], test = test, :
Reached total allocation of 6013Mb: see help(memory.size)
【问题讨论】:
【参考方案1】:您将文本列定义为varchar(max)
类型,因此无论在保存数据时是否指定varType
,它都会以这种方式存储。
尝试使用TEXT
列创建表,然后使用sqlSave
。这样,数据将被存储在行上下文之外,您不应该遇到截断问题。
【讨论】:
Aert,我测试了您的建议,但保存数据时出错。请参阅下面的结果。【参考方案2】:我遇到了类似的问题,最后做了以下事情:
# Finding the longest character
varTypes = c(col_in_question=sprintf("varchar(%s)", max(nchar(data$col_in_question))))
# Uploading data
sqlSave(channel = dbhandle,
dat = data,
tablename = "data_name",
rownames = FALSE,
varTypes = varTypes)
通过这种方式,您将 varchar 设置为数据集中的最大值,如果您没有任何极长的字符 (2 Gb),它应该可以工作。如果您坚持使用 varchar(max),那么您可以使用 sqlQuery 在您的数据集中进行更改。
【讨论】:
以上是关于RODBC 不会从数据框中保存超过 8k 的 varchar/text的主要内容,如果未能解决你的问题,请参考以下文章