От ошибки 1109 до ошибки 1242 MySQL
Я использую процедуру для расчета длины пользователя 'hiatus' (он же непредвиденные обстоятельства) из программы в нашей системе. Он запускается после процедуры, которая определяет статус пользователя в зависимости от того, завершают ли они свое ежедневное лечение и в какой степени.
Цель этой процедуры - записать длину непредвиденного события пользователя, добавив строку в таблицу со следующей схемой:
id_contingency int(11) NOT NULL AUTO_INCREMENT,
id_user int(11) DEFAULT NULL,
date_start date DEFAULT NULL,
program_day int(11) DEFAULT NULL,
date_end date DEFAULT NULL,
total_days int(11) DEFAULT NULL,
latest_tf_id archer(255) DEFAULT NULL
Я подумал добавить это как триггер при обновлении таблицы user_status, но я не могу рисковать ошибкой, препятствующей обновлению этой таблицы. Итак, эта процедура сначала закрывает непредвиденные расходы, которые ранее были открыты, когда пользователь впервые вошел в перерыв, но теперь возобновил работу программы, а затем открывает новые непредвиденные расходы для пользователей, которые впервые начали перерыв в лечении. Затем он остается открытым, пока они не возобновят программу, и вычисляет, как долго они находились в режиме ожидания.
Это была моя оригинальная процедура, и она вернула ошибку 1109 (неизвестная таблица tbl_user_status):
DELIMITER $$
CREATE DEFINER=CURRENT_USER PROCEDURE `proc_cont_calc`
NO SQL
BEGIN
#CLOSE OPEN CONTINGENCIES FIRST or d0 > d1
CASE
WHEN tbl_user_status.d4 = 1 AND tbl_user_status.d2 > 0 AND tbl_user_status.user_status = 'seguimiento' THEN
UPDATE tbl_user_contingency, tbl_user_status SET
tbl_user_contingency.date_end = CURRENT_DATE,
tbl_user_contingency.total_days = DATEDIFF(tbl_user_contingency.date_start, tbl_user_contingency.date_end),
tbl_user_contingency.updated_by = 'proc_cont.close'
WHERE tbl_user_contingency.date_end = '' AND tbl_user_contingency.id_smoker = tbl_user_status.id_smoker LIMIT 1;
#OPEN NEW CONTINGENCIES
WHEN tbl_user_status.d5 = 1 AND tbl_user_status.d4 = 0 AND tbl_user_status.user_status = 'contingencia' THEN
INSERT INTO tbl_user_contingency (id_smoker, roadmap_day, date_start, latest_tf_id, updated_by) SELECT
id_smoker, roadmap_day, CURRENT_DATE, latest_tf_id, 'proc_cont.open' FROM tbl_user_status;
END CASE;
END$$
DELIMITER;
Поэтому я попробовал это (среди прочего):
CASE
WHEN (SELECT d4 FROM tbl_user_status) = 1 AND (SELECT d2 FROM tbl_user_status) > 0 AND (SELECT user_status FROM tbl_user_status) = 'seguimiento' THEN
UPDATE tbl_user_contingency, tbl_user_status SET
tbl_user_contingency.date_end = CURRENT_DATE,
tbl_user_contingency.total_days = DATEDIFF(tbl_user_contingency.date_start, tbl_user_contingency.date_end),
tbl_user_contingency.updated_by = 'proc_cont.close'
WHERE tbl_user_contingency.id_smoker = tbl_user_status.id_smoker LIMIT 1;
#OPEN NEW CONTINGENCIES
WHEN (SELECT d5 FROM tbl_user_status) = 1 AND (SELECT d4 FROM tbl_user_status) = 0 AND (SELECT user_status FROM tbl_user_status) = 'contingencia' THEN
INSERT INTO tbl_user_contingency (id_smoker, roadmap_day, date_start, latest_tf_id, updated_by) SELECT
id_smoker, roadmap_day, CURRENT_DATE, latest_tf_id, 'proc_cont.open' FROM tbl_user_status;
END CASE;
И теперь я получаю ошибку 1242, возвращающую несколько строк.
Как я могу заставить эту процедуру работать правильно? Спасибо!
ОБНОВЛЕНИЕ - Я попробовал предложение @P.Salmon просто обновить строки, но не все поля были заполнены, или обновление превышает предыдущие непредвиденные обстоятельства.
Спасибо!
1 ответ
Оператор case здесь не нужен, просто переместите условия, например, в условия where
UPDATE tbl_user_contingency join tbl_user_status on tbl_user_contingency.id_smoker = tbl_user_status.id_smoker
SET
tbl_user_contingency.date_end = CURRENT_DATE,
tbl_user_contingency.total_days = DATEDIFF(tbl_user_contingency.date_start, tbl_user_contingency.date_end),
tbl_user_contingency.updated_by = 'proc_cont.close'
WHERE tbl_user_contingency.date_end = '' AND
tbl_user_status.d4 = 1 AND tbl_user_status.d2 > 0 AND tbl_user_status.user_status = 'seguimiento'
;
INSERT INTO tbl_user_contingency (id_smoker, roadmap_day, date_start, latest_tf_id, updated_by)
SELECT
id_smoker, roadmap_day, CURRENT_DATE, latest_tf_id, 'proc_cont.open'
FROM tbl_user_status
where tbl_user_status.d5 = 1 AND tbl_user_status.d4 = 0 AND tbl_user_status.user_status = 'contingencia'
;
Вы могли бы улучшить свой вопрос и получить тем самым лучший ответ, если бы вы описали, что именно вы пытаетесь сделать, вместо того, чтобы заставлять нас гадать путем обратного инжиниринга двух нерабочих сегментов кода, добавляя определения таблиц, примеры данных и ожидаемый вывод в виде текста в ваш вопрос. Кстати, я надеюсь, что у вас есть механизм, который не позволит этой вещи делать вещи более одного раза.