here is what im trying to do:
Table called departments has many-to-many relation with table called employees. so, table department_employees has columns: department_id, employee_id, is_active.
indexed department_id, employee_id as pk.
I get a string of employees ids like '12,15,18,19'. I get the department id.
I call a Mysql stored procedure (routine) that should:
CREATE PROCEDURE (IN @dep_id INT, IN @emp_ids TEXT)
INSERT INTO TBL_DEPARTMENT_EMPLOYEES (DEPARTMENT_ID, EMPLOYEE_ID, IS_ACTIVE) SELECT @dep_id, EMPLOYEE_ID, 1 FROM TBL_EMPLOYEES WHERE FIND_IN_SET(EMPLOYEE_ID, @emp_ids) ON DUPLICATE KEY UPDATE IS_ACTIVE=1;
UPDATE TBL_DEPARTMENT_EMPLOYEES SET IS_ACTIVE=0 WHERE DEPARTMENT_ID=@dep_id AND NOT FIND_IN_SET(EMPLOYEE_ID, @emp_ids);
only the first query runs and i guess the second one cant because of locking or something, i tried the TRANSACTION - COMMIT trick, didnt work. I thought maybe one of the awesome guys here can help or eben make it all run in a single query. thanks!
This procedure is not pretty, but its the best I can come up with given the concatenated IDs. It should also work faster than the FIND_IN_SET solution, because it can use the index on 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 ;