提问人:Jon 'links in bio' Ericson 提问时间:8/11/2018 最后编辑:CommunityJon 'links in bio' Ericson 更新时间:6/19/2023 访问量:1638
如何从 dplyr::tbl 获取详细的数据库错误消息?
How might I get detailed database error messages from dplyr::tbl?
问:
我正在使用 R 绘制我从数据库中提取的一些数据(具体来说,是 Stack Exchange 数据转储):
dplyr::tbl(serverfault,
dbplyr::sql("
select year(p.CreationDate) year,
avg(p.AnswerCount*1.0) answers_per_question,
sum(iif(ClosedDate is null, 0.0, 100.0))/count(*) close_rate
from Posts p
where PostTypeId = 1
group by year(p.CreationDate)
order by year(p.CreationDate)
"))
查询在 SEDE 上工作正常,但我在 R 控制台中收到此错误:
Error: <SQL> 'SELECT *
FROM (
select year(p.CreationDate) year,
avg(p.AnswerCount*1.0) answers_per_question,
sum(iif(ClosedDate is null, 0.0, 100.0))/count(*) close_rate
from Posts p
where PostTypeId = 1
group by year(p.CreationDate)
order by year(p.CreationDate)
) "zzz11"
WHERE (0 = 1)'
nanodbc/nanodbc.cpp:1587: 42000: [FreeTDS][SQL Server]Statement(s) could not be prepared.
我估计“无法准备语句”意味着 SQL Server 出于某种原因不喜欢该查询。不幸的是,它没有给出任何关于出了什么问题的提示。在摆弄了一会儿查询后,我注意到根据错误消息,它被包装在一个子选择中。复制并执行由链中的某个库构造的完整查询时,SQL Server 给了我这个信息量更大的错误消息:
除非还指定了 TOP、OFFSET 或 FOR XML,否则 ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效。
现在解决方案很明显:删除(或注释掉)该子句。但是 R 控制台中的详细错误消息在哪里?我正在使用 Rstudio,如果这很重要的话。如果我能在我正在处理的代码旁边获得完整的异常,它将帮助我更快地修复错误。(需要明确的是,我经常从 dplyr::tbl 收到神秘的错误,并且通常使用二进制搜索调试来修复它们。order by
答:
要从 dplyr::tbl 获取更详细的错误消息,您可以修改代码以包含 tryCatch() 函数。此功能允许您捕获和处理错误,包括提取详细的错误消息。 尝试修改代码,如下所示。
result <- tryCatch({
dplyr::tbl(serverfault,
dbplyr::sql("
select year(p.CreationDate) year,
avg(p.AnswerCount*1.0) answers_per_question,
sum(iif(ClosedDate is null, 0.0, 100.0))/count(*) close_rate
from Posts p
where PostTypeId = 1
group by year(p.CreationDate)
order by year(p.CreationDate)
"))
}, error = function(e) {
message("Detailed error message: ", conditionMessage(e))
stop(e)
})
# Continue with your code using the `result` object if no error occurred
在修改后的代码中,tryCatch() 函数包装了 dplyr::tbl() 调用。在 tryCatch() 函数中,使用 error 参数定义错误处理程序。在错误处理程序中,您可以使用 conditionMessage() 函数访问详细的错误消息。
如果发生错误,错误处理程序将使用 message() 将详细的错误消息打印到控制台,然后使用 stop(e) 重新引发错误以停止执行进一步的代码。如果未发生错误,代码将继续使用 result 对象。
此方法允许您在使用 dplyr::tbl 或其他可能引发错误的函数时捕获和显示详细的错误消息。
评论
DBI::dbGetQuery()
dbplyr::sql
The ORDER BY clause ... is also specified.*
dbplyr