R使用ODBC Driver 17连SQL取数时nvarchar(MAX)字段截断为255字符问题
问题成因
ODBC Driver 17 for SQL Server 与旧版{SQL Server}遗留驱动的长文本读取默认逻辑存在差异:新版驱动在查询元数据预读取阶段,未显式开启长文本兼容时,会将nvarchar(MAX)类型按普通短字符串列处理,单字段默认读取缓冲区上限为255字符,超出部分直接截断。旧版驱动未设置该预校验截断逻辑,因此可以直接读取全量长文本,但旧驱动已停止官方维护,不兼容SQL Server 2016及以上版本的新特性与TLS安全协议,不建议长期使用。
可落地方案
按稳定性优先级从高到低排列:
- 连接串追加长文本兼容参数
这是稳定性最高的方案,不需要修改业务查询逻辑,仅需在ODBC Driver 17的连接串中添加LongDataCompat=1配置项,显式告知驱动启用大对象字段适配,自动调整长文本列的读取缓冲区大小,参考连接代码:
该参数在ODBC Driver 13及以上版本均支持,适配所有conn <- odbcDriverConnect(paste0( "driver={ODBC Driver 17 for SQL Server};server=你的数据库实例地址;database=目标库名;uid=登录账号;pwd=登录密码;", "LongDataCompat=1" ))varchar(MAX)、nvarchar(MAX)、varbinary(MAX)类型大字段的读取场景。 - 查询阶段显式转换字段类型绕开元数据判定
若无法修改连接串配置,可在编写查询SQL时,将目标长文本字段显式转换为ntext类型,驱动会直接将其识别为大对象类型,不会触发255字符截断,参考SQL写法:
该方案为临时绕路方案,转换后字段会失去原生SELECT 其他字段, CONVERT(NTEXT, 长文本nvarchar字段名) AS long_content FROM 目标表nvarchar(MAX)类型标记,后续如果需要回写数据库需要额外做类型转换。 - 调整RODBC全局字段长度配置
建立连接前,通过全局option设置RODBC包的nvarchar类型字段默认读取长度,将阈值设置为大于业务场景中单字段最大字符数即可,例如单字段最长存储40000字符时,可设置50000的冗余值:
该配置为全局生效,会让所有nvarchar类型列的读取缓冲区都按设定值分配内存,大表查询场景下内存占用会略高于前两种方案。options(odbcFieldSizes = c(nvarchar = 50000))
注意:不建议为解决该问题回退使用旧版
{SQL Server}驱动,该驱动已停止维护,连接SQL Server 2016及以上版本时会出现TLS握手失败、新语法不兼容、加密连接不支持等问题。
内容的提问来源于stack exchange,提问作者manu p
相关产品推荐
相关产品推荐

