2013-07-10 3 views
0

вот что им пытается сделать:Как вставить или обновить все значения в FIND_IN_SET и обновлять НЕ FIND_IN_SET на дубликате ключа обновления

Таблицы называемых отделы имеют много-ко-многим отношений со столом называют сотрудниками. Таким образом, table department_employees имеет столбцы: department_id, employee_id, is_active.

с индексом department_id, employee_id as pk.

Я получаю строку идентификаторов сотрудников, таких как '12, 15,18,19 '. Я получаю идентификатор отдела.

я называю Mysql хранимой процедуры (рутина), который должен:

  • вставки всех сотрудников отдела
  • , если они существуют, и не активен, чем активировать
  • все остальные сотрудники должны быть выключены

CREATE PROCEDURE (ВО @dep_id INT, IN @emp_ids TEXT)

INSERT INTO TBL_DEPARTMENT_EMPLOYEES (department_id, EMPLOYEE_ID, IS_ACTIVE) ВЫБОР @dep_id, EMPLOYEE_ID, 1 ОТ TBL_EMPLOYEES ГДЕ FIND_IN_SET (EMPLOYEE_ID, @emp_ids) ПО DUPLICATE KEY UPDATE IS_ACTIVE = 1;

ОБНОВЛЕНИЕ TBL_DEPARTMENT_EMPLOYEES SET IS_ACTIVE = 0 ГДЕ department_id = @ dep_id И НЕ FIND_IN_SET (EMPLOYEE_ID, @emp_ids);

только первый запрос запускается, и я предполагаю, что второй из них не работает из-за блокировки или чего-то еще, Я пробовал трюк TRANSACTION-COMMIT, не работал. Я подумал, что, может быть, один из удивительных парней может помочь или сделать все, чтобы запустить все в одном запросе. спасибо!

ответ

2

Эта процедура не очень красивая, но ее лучшее, что я могу придумать, с учетом конкатенированных идентификаторов. Он также должен работать быстрее, чем решение FIND_IN_SET, потому что он может использовать индекс для EMPLOYEE_ID.

CREATE PROCEDURE `test`(IN `dep_id` INT, IN `emp_ids` TEXT) 
    LANGUAGE SQL 
    NOT DETERMINISTIC 
    MODIFIES SQL DATA 
    SQL SECURITY DEFINER 
    COMMENT '' 
BEGIN 
START TRANSACTION; 
IF(emp_ids REGEXP '^[0-9,]+$') THEN #this will NOT guarantee a valid query but will prevent injections 
    UPDATE TBL_DEPARTMENT_EMPLOYEES SET IS_ACTIVE=0 WHERE DEPARTMENT_ID=dep_id; 
    SET @q = CONCAT(' 
     INSERT INTO TBL_DEPARTMENT_EMPLOYEES (DEPARTMENT_ID, EMPLOYEE_ID, IS_ACTIVE) 
     SELECT ?, EMPLOYEE_ID, 1 
     FROM TBL_EMPLOYEES 
     WHERE EMPLOYEE_ID IN (',emp_ids,') 
     ON DUPLICATE KEY UPDATE IS_ACTIVE=1; 
    '); 
    PREPARE stmt1 FROM @q; 
    SET @dep_id = dep_id; 
    EXECUTE stmt1 USING @dep_id; 
    DEALLOCATE PREPARE stmt1; 
END IF; 
COMMIT; 
END ; 
+0

работал. спасибо @Vatev – Bergkamp

+0

Спасибо! Это сработало и для меня. Ох, я мог бы поддержать только один раз :-( –

Смежные вопросы