我遇到了一个问题:我想更新一个插入带触发器的表的记录:
DELIMITER $$
CREATE TRIGGER moodle.update_lang
AFTER INSERT
ON moodle.mdl_user FOR EACH ROW
BEGIN
update moodle.mdl_user SET lang='hu' WHERE lang='en';
END$$
DELIMITER ;
因此,当我想立即插入一行时,它会给出一个错误,即由于某个过程已经在使用该行,因此无法插入该行。你能给出任何解决方案吗?这种方法是否可用,还是应该从不同角度解决问题?提前谢谢!
答案 0 :(得分:1)
根据评论:)
您需要BEFORE INSERT
触发器。在该触发器中,您可以在记录到达永久存储之前更改记录。使用您的示例,此触发器将定义如下:
DELIMITER $$
CREATE TRIGGER moodle.update_lang
BEFORE INSERT
ON moodle.mdl_user FOR EACH ROW
BEGIN
SET NEW.lang='hu';
END$$
DELIMITER ;
你不能在触发引用的同一个表上使用UPDATE
的原因是因为它可能(并且会)导致无限循环。
注意:我没有对此进行测试,但根据您的评论判断它似乎正在运行。祝你好运!
答案 1 :(得分:1)
我不建议使用数据库触发器,因为Moodle可以使用多个数据库。您可能需要在将来转移到另一个数据库。
您可以在网站管理员中设置默认语言 - >语言 - >语言设置 - >默认语言。或者直接到/admin/settings.php?section=langsettings
或者将其添加到config.php
$CFG->lang = 'hu';
或回复user_created
事件并更新记录
https://docs.moodle.org/dev/Events_API#Handling_an_event
创建本地插件
https://docs.moodle.org/dev/Local_plugins
然后添加以下代码:
在local/yourplugin/db/events.php
$handlers = array (
'user_created' => array (
'handlerfile' => '/local/yourplugin/locallib.php',
'handlerfunction' => 'local_yourplugin_user_created',
'schedule' => 'instant',
'internal' => 1,
),
);
然后在/local/yourplugin/locallib.php
function local_yourplugin_user_created($eventdata) {
global $DB;
$userid = $eventdata->objectid;
$DB->set_field('user', 'lang', 'hu', array('id' => $userid);
return true;
}