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

Moodle新活动创建成功但无法向数据库添加实例,出现“Error reading from database”错误求助

排查Moodle activity_add_instance无法插入数据库的问题

我来帮你一步步梳理这个问题,毕竟在开发Moodle插件时,数据库操作的隐性错误确实容易让人头疼。你提到活动创建成功,但testnew表没有新增数据,还出现了“Error reading from database”的提示,咱们从以下几个方向排查:

1. 确认数据库表结构是否匹配

Moodle的$DB->insert_record()会严格匹配表字段和传入对象的属性,如果testnew表有非空且无默认值的字段,但$data里没有赋值,插入就会失败。你可以通过以下方式检查:

  • 直接查看数据库中testnew表的字段结构,确认是否有必填字段遗漏;
  • 在函数里临时添加调试代码,打印表字段和$data的内容:
    debugging('testnew表字段: ' . print_r($DB->get_columns('testnew'), true), DEBUG_DEVELOPER);
    debugging('传入的$data: ' . print_r($data, true), DEBUG_DEVELOPER);
    

2. 开启Moodle调试模式,暴露具体错误

默认情况下Moodle会隐藏详细错误信息,你需要修改config.php开启调试:

$CFG->debug = DEBUG_DEVELOPER;
$CFG->debugdisplay = true;

这样再创建活动时,就能看到insert_record()失败的具体原因(比如字段类型不匹配、权限不足等),这是排查这类问题最有效的方法。

3. 给数据库操作添加异常捕获

Moodle的数据库操作失败时会抛出dml_exception,你可以在代码里捕获并打印错误:

function activity_add_instance($data){
    global $DB;
    $data->timecreated = time();
    $data->timemodified = time();
    $cmid = $data->coursemodule;

    try {
        $data->id = $DB->insert_record('testnew', $data);
    } catch (dml_exception $e) {
        debugging('插入testnew表失败: ' . $e->getMessage(), DEBUG_DEVELOPER);
        return false;
    }

    // 后续代码...
    $DB->set_field('course_modules', 'instance', $data->id, ['id' => $cmid]);
    $data->cmid = $data->coursemodule;
    return $data->id;
}

4. 检查$data对象的完整性

确认$data->coursemodule是否有有效值,有时候插件表单的字段名可能和预期不符,导致$cmid为空,后续的set_field也会失效。可以用var_dump($data)临时打印$data的所有属性,确认关键字段都存在。

5. 验证数据库权限

虽然概率较低,但要确认Moodle使用的数据库账号是否对testnew表有INSERT权限。如果是手动创建的表,可能没有给该账号授权,导致插入失败。

优化后的完整代码示例

结合以上排查点,优化后的代码会更健壮:

function activity_add_instance($data){
    global $DB;

    // 调试:打印$data内容
    debugging('准备插入的数据: ' . print_r($data, true), DEBUG_DEVELOPER);

    $data->timecreated = time();
    $data->timemodified = time();
    $cmid = isset($data->coursemodule) ? $data->coursemodule : 0;

    if (empty($cmid)) {
        debugging('缺少coursemodule ID', DEBUG_DEVELOPER);
        return false;
    }

    try {
        $data->id = $DB->insert_record('testnew', $data);
    } catch (dml_exception $e) {
        debugging('插入失败: ' . $e->getMessage(), DEBUG_DEVELOPER);
        return false;
    }

    if (empty($data->id)) {
        debugging('插入后未获取到新记录ID', DEBUG_DEVELOPER);
        return false;
    }

    // 更新course_modules的instance字段
    $update_result = $DB->set_field('course_modules', 'instance', $data->id, ['id' => $cmid]);
    if (!$update_result) {
        debugging('更新course_modules失败,回滚插入记录', DEBUG_DEVELOPER);
        $DB->delete_records('testnew', ['id' => $data->id]);
        return false;
    }

    $data->cmid = $data->coursemodule;
    return $data->id;
}

开启调试后,你就能快速定位到具体问题,大部分情况都是字段不匹配或者必填字段未赋值导致的。

内容的提问来源于stack exchange,提问作者Aya Ashraf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 08:37:27