SQL Server执行R存储过程报WITH RESULT SETS结果集列数不匹配错误
故障根本原因
报错由两个逻辑叠加触发,和WITH RESULT SETS写法本身无关:
- 外部脚本输出的
Rows Read: 0, Total Rows Processed: 0日志已经明确:传入rxPredict做预测的数据集Pred_Data是0行空集。 - RevoScaleR的
rxPredict函数接收到0行输入时,不会返回常规的单列预测结果结构,而是直接返回NULL。R原生cbind()函数拼接多对象时会自动丢弃所有值为NULL的入参,最终赋值给OutputDataSet的结果仅保留Pred_Data$key1、Pred_Data$flag两列,和WITH RESULT SETS声明的3列结构不匹配,触发11537错误。
其余同结构存储过程无同类问题,是因为那些场景下传入预测的数据集存在有效数据行,rxPredict正常返回预测列,cbind拼接后列数符合声明要求,不会触发校验失败。
排查步骤
- 校验输入数据源:单独执行赋值给
@q的输入查询语句,确认返回结果是否为0行,重点检查查询的过滤条件、表关联逻辑是否误将所有待预测数据过滤。 - 调试R脚本中间对象:在
rxPredict执行行后新增cat(str(predictions))打印语句,运行存储过程查看外部脚本输出,确认空输入场景下predictions的返回值是否为NULL。 - 校验实际输出结构:在
OutputDataSet赋值行后新增cat(ncol(OutputDataSet))打印语句,确认空输入场景下实际输出的列数是否为2。
解决方案
针对空输入场景做结构兼容,避免列数丢失,二选一即可:
- 方案1:提前拦截空输入。R脚本中在执行预测前先判断输入数据集行数,若为0行则直接手动构造符合3列结构的空数据框赋值给输出,跳过后续预测逻辑,参考代码:
if(nrow(Pred_Data) == 0){ OutputDataSet <- data.frame( key1 = character(0), flag = character(0), predictions = numeric(0) ) } else { predictions <- rxPredict(model, Pred_Data) OutputDataSet <- cbind(Pred_Data$key1, Pred_Data$flag, predictions) }
- 方案2:兼容rxPredict空返回值。判断
predictions是否为NULL,如果是则手动生成和输入数据行数匹配的数值型空列,再执行拼接,避免cbind自动丢列。
额外建议:给拼接后的输出数据集显式设置和WITH RESULT SETS一致的列名、列类型,避免后续出现列顺序错位、类型隐式转换失败的隐性问题。
内容的提问来源于stack exchange,提问作者adey27
相关产品推荐
相关产品推荐

