DELIMITER $$ CREATE PROCEDURE sp_add_points( IN p_session_id INT, IN p_team_id VARCHAR(10), IN p_points INT ) BEGIN DECLARE v_teams JSON; DECLARE v_idx INT DEFAULT 0; DECLARE v_max_idx INT; DECLARE v_current_team_id VARCHAR(10); DECLARE v_current_score INT; DECLARE v_found BOOLEAN DEFAULT FALSE; -- Lấy dữ liệu JSON teams từ bảng pk_sessions SELECT teams INTO v_teams FROM pk_sessions WHERE id = p_session_id; -- Nếu không tìm thấy session thì báo lỗi IF v_teams IS NULL THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'PK session not found'; END IF; -- Tính chỉ số cuối cùng của mảng JSON (độ dài - 1) SET v_max_idx = JSON_LENGTH(v_teams) - 1; -- Duyệt qua từng phần tử trong mảng JSON để tìm team có id khớp WHILE v_idx <= v_max_idx AND NOT v_found DO SET v_current_team_id = JSON_UNQUOTE( JSON_EXTRACT(v_teams, CONCAT('$[', v_idx, '].id')) ); IF v_current_team_id = p_team_id THEN -- Tìm thấy team → lấy điểm hiện tại SET v_current_score = CAST( JSON_EXTRACT(v_teams, CONCAT('$[', v_idx, '].score')) AS UNSIGNED ); -- Cập nhật điểm mới (cộng thêm p_points) SET v_teams = JSON_SET( v_teams, CONCAT('$[', v_idx, '].score'), v_current_score + p_points ); SET v_found = TRUE; END IF; SET v_idx = v_idx + 1; END WHILE; -- Nếu không tìm thấy team nào có id khớp thì báo lỗi IF NOT v_found THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Team not found in session'; END IF; -- Cập nhật lại dữ liệu JSON vào bảng và cập nhật thời gian UPDATE pk_sessions SET teams = v_teams, updated_at = NOW(3) WHERE id = p_session_id; END$$ DELIMITER ;