You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MariaDB执行带递归CTE的DELETE语句报1046未选择数据库错误

问题原因及解决方案

触发原因

该错误是MariaDB 10.5.11及更早版本的已知解析BUG:当预处理包含WITH RECURSIVE递归CTE子句的DML(DELETE/INSERT/UPDATE)语句时,解析器会丢失当前连接已配置的默认数据库上下文,因此误判没有选择数据库抛出1046错误。该问题对普通SELECT查询无影响,且官方已在MariaDB 10.6.5及后续稳定版本中完成修复,这也是同一份代码无需修改即可在MySQL 8上正常运行的原因。

可选解决方案

  • 升级MariaDB版本:直接将MariaDB升级到10.6.5或更高的稳定版本,升级完成后原有代码无需任何修改即可正常运行,是成本最低的解决方案。
  • 为所有表名增加数据库前缀:在你读取的SQL语句中,给所有显式声明的表名前加上所属数据库名,强制指定表的归属,即可绕开上下文丢失的问题,修改后的SQL示例如下(替换your_db_name为实际的数据库名):
DELETE FROM `your_db_name`.`shares` WHERE `itemuuid` in (
  WITH RECURSIVE files_paths (id, parent) AS
  (
    SELECT uuid, parentuuid
      FROM `your_db_name`.`core_data`
      WHERE uuid = ?
    UNION ALL
    SELECT e.uuid, e.parentuuid
      FROM files_paths AS ep JOIN `your_db_name`.`core_data` AS e
        ON ep.id = e.parentuuid
  )
  SELECT id FROM files_paths
)
  • 预处理前显式指定数据库:在执行prepare操作前,先通过当前连接执行一次USE语句重新指定默认数据库,示例代码如下:
// 加在prepare之前
$this->dbcon->query("USE your_db_name");
$stmt = $this->dbcon->prepare($query);
  • 改写SQL避免使用递归CTE:如果暂时无法升级也不想修改原有SQL结构,可以将递归查询逻辑改写为存储过程或者嵌套子查询实现,不过改造成本相对更高,不优先推荐。

内容的提问来源于stack exchange,提问作者Francesco Piraneo G.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 08:30:00