MySQL альтернатива по дублированию ключа обновления

Я пытаюсь вытащить несколько таблиц для вставки в таблицу для создания назначений ролей в базе данных moodle на основе созданных категорий, но мне нужно, чтобы она обновлялась по дублированному ключу, но я не могу использовать ON DUPLICATE KEY UPDATE, потому что поля im пытаются соответствие по идентификатору роли, идентификатору контекста и идентификатору пользователя не являются первичными ключами в таблице mdl_role_assignments.

insert into vclassmoodle.mdl_role_assignments (roleid,contextid,userid,timemodified,modifierid,itemid,sortorder) select 
mdl_role.id as roleid, mdl_context.id as contextid, mdl_user.id as userid, unix_timestamp() as timemodified, 3 as modifierid, 0 as itemid, 0 as sortorder
from
mdl_context
    left join
mdl_course_categories ON mdl_context.instanceid = mdl_course_categories.id
    left join
mdl_user ON mdl_course_categories.idnumber = mdl_user.idnumber
    join
mdl_role ON mdl_role.shortname = 'manager'
where mdl_context.contextlevel = 40 and mdl_course_categories.depth > 1

Дайте мне знать, если мне нужно что-то уточнить

Спасибо

1 ответ

Только что посмотрел на функцию role_assign() в /lib/accesslib.php

Если есть дубликат, он не обновляется, поэтому вы можете просто игнорировать дубликаты.

Хотя вам действительно следует использовать функцию role_assign(), а не вставлять данные напрямую. В случае, если назначение роли изменится в будущем, но также и потому, что оно вызывает событие role_assigned, которое может использоваться в другом месте.

Все еще используйте ваш запрос, но игнорируйте существующие записи и создайте цикл для вызова role_assign(), что-то вроде этого

SELECT mdl_role.id as roleid,
       mdl_context.id as contextid,
       mdl_user.id as userid
FROM mdl_context
JOIN mdl_course_categories ON mdl_context.instanceid = mdl_course_categories.id
JOIN mdl_user ON mdl_course_categories.idnumber = mdl_user.idnumber
JOIN mdl_role ON mdl_role.shortname = 'manager'
WHERE mdl_context.contextlevel = 40
AND mdl_course_categories.depth > 1
AND NOT EXISTS (
    SELECT mdl_role_assignments.id
    FROM mdl_role_assignments
    WHERE mdl_role_assignments.roleid = mdl_role.id
    AND mdl_role_assignments.contextid = mdl_context.id
    AND mdl_role_assignments.userid = mdl_user.id
    AND mdl_role_assignments.itemid = 0
    AND mdl_role_assignments.component = '')

Обратите внимание, что дубликат представляет собой комбинацию roleid, userid и contextxtid, но также является компонентом и itemid. Поэтому компонент = '' тоже нужно проверить.

Другие вопросы по тегам