Потеряно соединение с сервером MySQL во время ошибки запроса, когда я пытаюсь использовать функцию

Я пытаюсь создать функцию, которая проверяет, находится ли какая-либо дата между, скажем, диапазоном дат A и B, между диапазоном дат C и D. Всякий раз, когда я пытаюсь запустить функцию, MySQL Workbench всегда выдает код ошибки: 2013 Потеряно соединение с сервером MySQL во время запроса. Я предполагаю, что эта ошибка возникает из-за того, что цикл работает вечно (пожалуйста, поправьте меня, если я думаю об этом совершенно неправильно).

Код таблицы:

CREATE TABLE TESTING(
LeaveStart DATE,
LeaveEnd DATE,
ProjectStart DATE,
ProjectEnd DATE,
Det BOOL,
ID INT);

Код вставки значения:

INSERT INTO TESTING VALUES('2018-01-01','2018-01-31','2018-01-10','2018-01-30',FALSE,1);
INSERT INTO TESTING VALUES('2018-01-01','2018-01-31','2018-01-10','2018-01-30',FALSE,2);

Функция:

DELIMITER //
CREATE FUNCTION SALARY_DEDUCTION (LeaveStart Date, LeaveEnd Date, ProjectStart DATE, ProjectEnd Date)
RETURNS BOOL NO SQL
DETERMINISTIC 
BEGIN
    DECLARE DET BOOL DEFAULT FALSE;
    DECLARE DT DATE DEFAULT LeaveStart;
    WHILE LeaveStart < LeaveEnd DO
    IF DT BETWEEN ProjectStart AND ProjectEnd THEN
    SET DET = TRUE;
    ELSE 
    SET DET = FALSE;
    SET DT = DATE_ADD(DT, INTERVAL 1 DAY);
    END IF;
    END WHILE;
    RETURN DET;
END ; //

DELIMITER ;

Код вызова/водителя:

UPDATE TESTING AS T
SET 
T.Det = SALARY_DEDUCTION(T.LeaveStart,T.LeaveEnd,T.ProjectStart,T.ProjectEnd)
WHERE 
T.ID=1;

Примечание. Код драйвера может выдать код ошибки 1175: безопасное обновление. Его можно отключить, указав SET SQL_SAFE_UPDATES=0 перед кодом драйвера. Если бы кто-то мог также объяснить, почему он выдает ошибку, это было бы здорово.

DB-Fiddle: https://www.db-fiddle.com/f/4Bof1gdHRnkSYJwVZekRJ9/1

Обновлено:

DELIMITER //
CREATE FUNCTION SALARY_DEDUCTION_3(LeaveStart Date, LeaveEnd Date, ProjectStart DATE, ProjectEnd Date)
RETURNS BOOL NO SQL
DETERMINISTIC 
BEGIN
    DECLARE DET BOOL DEFAULT FALSE;
    DECLARE CD DATE DEFAULT LeaveStart;
    myloop: WHILE CD < LeaveEnd DO
    IF CD BETWEEN ProjectStart AND ProjectEnd THEN
    SET DET = TRUE;
    LEAVE myloop;
    END IF;
    SET CD = DATE_ADD(CD, INTERVAL 1 DAY);
    END WHILE myloop;
    RETURN DET;
END ; //

DELIMITER ;
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
0
98
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш код создает бесконечный цикл (LeaveStart < LeaveEnd всегда равно true).

Кроме того, взгляните на код, если вам вообще нужен цикл. В настоящее время он вам не нужен, так как значение DET будет определяться из последнего раунда цикла. Все остальные раунды ничего не значат.

Вы можете просто сделать:

UPDATE TESTING
SET Det = (LeaveStart<ProjectEnd AND LeaveEnd>=ProjectStart AND LeaveStart<LeaveEnd)
WHERE ID=1;

Спасибо за ответ, теперь я понимаю свою ошибку с всегда истинным LeaveStart<LeaveEnd, я обновил эту ошибку в Edit (1) выше, а также добавил перерыв в цикле для выхода кода после того, как DET установлено в TRUE. Казалось, это решило проблему! Не знаю, как я это пропустил. Цикл в коде предназначен для увеличения дат от LeaveStart до LeaveEnd при проверке каждой даты, находится ли она между диапазоном ProjectStart и ProjectEnd. Если есть лучший способ сделать это, я буду признателен за любые предложения.

Jaisal Singhani 17.11.2022 20:19

@ДжайсалСингхани. Добавлен образец без цикла

slaakso 17.11.2022 22:48

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