knitr SQL 引擎日趋成熟

knitr SQL 引擎日趋成熟

💡 原文英文,约800词,阅读约需3分钟。
📝

内容提要

knitr 的 SQL 引擎近期新增多项功能:sql.interlaced 支持拆分并逐条执行多语句;sql.result.fun 可返回惰性句柄供 dplyr 处理;引擎能识别非查询语句并返回影响行数,可通过 sql.statement.msg 报告;sql.args 用于传递后端参数。

🔎

延伸解读

多语句执行更可靠

过去,一个 SQL 代码块中的多条语句会被一次性提交,某些 DBI 后端可能静默丢弃第一条之后的结果。新增的 sql.interlaced 选项将代码块拆分为独立语句,按顺序执行,并像 R 代码块那样交替输出每条语句的源代码和结果。拆分由纯 R 辅助函数完成,能正确忽略字符串字面量、带引号标识符和注释中的分号,无需外部 SQL 解析器。若某条语句失败,执行会就此停止,并遵循 error 选项。

惰性结果与 dplyr 协作

默认情况下,SQL 引擎会立即通过 DBI 执行查询并收集结果。若希望保留惰性句柄以便后续用 dplyr 处理,可使用新的 sql.result.fun 选项,用自定义函数替代内置执行逻辑。例如,传入 function(conn, query) dplyr::tbl(conn, dbplyr::sql(query)),再结合 output.var,就能将惰性对象赋给变量而不立即收集,同时代码块仍享有 SQL 引擎的语法高亮。这样既能继续编写真正的 SQL,又能把结果交给下游 dplyr 处理。

非查询语句与影响行数

并非所有 SQL 语句都返回行。INSERT、UPDATE、DELETE 等语句返回受影响的行数,引擎现在能识别更多非 SELECT 关键字(如 ALTER、GRANT、MERGE、TRUNCATE、CALL 等),并将它们路由到 DBI::dbExecute() 而非 dbGetQuery(),从而避免某些驱动产生虚假警告。当自动检测出错时(例如 SELECT ... INTO 或 UPDATE ... RETURNING),可用 sql.is_statement 覆盖。受影响行数可通过 output.var 捕

后端参数传递更灵活

sql.args 是一个命名列表,会转发给底层 DBI 函数,让你无需引擎知晓即可设置任何后端特定参数。例如,sql.args=list(immediate=TRUE) 可传递给 DBI 调用。这些参数仅在提供时才会传递,否则 DBI 自身的默认值保持不变。此外,本次更新还包含其他改进,例如美元引号字符串不再触发插值代码问题。所有功能均处于开发版本中,安装命令可参考 backlog 摘要。

Q&A

knitr 的 SQL 引擎最近增加了哪些新功能?

新增了 sql.interlaced 选项,用于拆分并逐条执行多语句;sql.result.fun 选项,可返回惰性句柄供 dplyr 处理;引擎能识别非查询语句并返回影响行数,可通过 sql.statement.msg 报告;sql.args 用于传递后端参数。

sql.interlaced 选项有什么作用?

sql.interlaced 选项将包含多个以分号分隔的语句的 SQL 代码块拆分成单独的语句,按顺序执行,并将每个语句的源代码和结果作为交替的块输出,类似于 R 代码块回显每个表达式及其输出。拆分由纯 R 辅助函数完成,能忽略字符串字面量、带引号的标识符和注释中的分号,无需外部 SQL 解析器。如果某个语句失败,执行会停止(遵循 error 选项)。

如何使用 sql.result.fun 选项?

sql.result.fun 选项允许你用自己的函数(conn, query)替换内置的执行函数。例如,可以设置为 function(conn, query) dplyr::tbl(conn, dbplyr::sql(query)),结合 output.var 将惰性对象赋值给变量而不立即收集结果,同时代码块仍获得 SQL 引擎的语法高亮。这样你可以继续编写真正的 SQL,并将结果传递给下游的 dplyr 处理。

knitr 的 SQL 引擎如何处理非查询语句?

引擎现在能识别更多关键字(如 ALTER、GRANT、MERGE、TRUNCATE、CALL 等)作为非 SELECT 语句,并将它们路由到 DBI::dbExecute() 而不是 dbGetQuery(),从而避免某些驱动程序的虚假警告。当自动检测出错时(例如 SELECT ... INTO 或 UPDATE ... RETURNING),可以使用 sql.is_statement 覆盖。影响行数可通过 output.var 捕获,并可选地通过 sql.statement.msg 模板报告,其中 {n} 是计数。

sql.args 选项有什么用途?

sql.args 是一个命名列表,会转发给底层的 DBI 函数,因此你可以设置任何后端特定的参数,而无需引擎了解它们。这些参数仅在提供时传递,否则 DBI 自身的默认值保持不变。

这些新功能是否已经稳定发布?

这些功能都在开发版本中,尚未在稳定版发布。

🏷️

标签

➡️

继续阅读