Я делаю хранимую процедуру для обновления таблицы, и эта таблица имеет логическое имя: «Завершено», как поле. Это поле информирует нас о завершении игры. В моей задаче имеет смысл установить что-то как завершенное до истечения срока действия, поэтому я проверяю, имеет ли строка для обновления поле «Завершено» как истинное или дата истечения срока действия прошла.
SET @isFinished=0;
SELECT Finished INTO @isFinished FROM game WHERE ID = gameID;
-- gameID comes as a parameter
-- date comes as a parameter as well
IF DATEDIFF(STR_TO_DATE(date, "%Y-%m-%d") , CURDATE()) < 0 OR @isFinished<>0 THEN
select CONCAT("Game can't be updated because it's already finished. Days missing:",DATEDIFF( STR_TO_DATE(date, "%Y-%m-%d"), CURDATE() )," and @finished=", @isFinished, ", game=",gameID)
into @msg;
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = @msg;
END IF;
Проблема в том, что, когда я пытаюсь обновить незаконченную игру, она попадает в if и выдает сообщение об ошибке:
"sqlMessage: 'Игра не может быть обновлена, потому что она уже закончена. Дней не хватает: 337 и @ закончено = 1, игра = 2'".
быстрое примечание: переменная @isFinished никогда не используется, но в этом блоке кода.
Я всегда уверял, что значение "Finished" было 0 до того, как я его протестировал, и все же он продолжает выбирать его как 1 и, следовательно, попадает в if.
Я подумал, что это может быть из select ... into, поэтому я попробовал его из хранимой процедуры (буквально скопировать вставку, просто изменил «gameID» на фактический идентификатор, который я использую), и он работал отлично.
SELECT Finished INTO @isFinished FROM game WHERE ID = 2;
SELECT @isFinished
После этого я не знаю, что еще я могу проверить. Если бы кто-нибудь мог помочь, я был бы благодарен.
Изолированный тест:
create database test;
use test;
create table Tournament(
ID int(10) not null unique auto_increment,
Name varchar(250) not null,
Start_Date date not null,
End_Date date not null,
Primary key(ID)
);
create table Game(
ID int(10) not null unique auto_increment,
Tournament_ID int(10),
Date date,
Finished boolean,
Foreign Key(Tournament_ID) references Tournament(ID) ON DELETE CASCADE,
Primary Key(ID)
);
INSERT INTO Tournament VALUES(NULL, "tournament1", str_to_date("2020-06-01","%Y-%m-%d"), str_to_date("2020-07-01","%Y-%m-%d"));
INSERT INTO Game VALUES(NULL, 1, str_to_date("2020-06-02","%Y-%m-%d"), 0);
DELIMITER $$
DROP PROCEDURE IF EXISTS `UpdateGame`$$
CREATE PROCEDURE `UpdateGame`(IN gameID int, date varchar(10), finished boolean)
BEGIN
SET @isFinished=0;
SELECT Finished INTO @isFinished FROM game WHERE ID = gameID;
IF DATEDIFF(STR_TO_DATE(date, "%Y-%m-%d") , CURDATE()) < 0 OR @isFinished<>0 THEN
select CONCAT("Game can't be updated because it's already finished. Days missing:",DATEDIFF( STR_TO_DATE(date, "%Y-%m-%d"), CURDATE() )," and @finished=", @isFinished, ", game=",gameID)
into @msg;
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = @msg;
END IF;
UPDATE game SET Date=STR_TO_DATE(date, "%Y-%m-%d"), Finished=finished WHERE ID=gameID;
END$$
call UpdateGame(1,"2020-06-03",1);
SELECT * FROM game;
SELECT Finished INTO @isFinished FROM game WHERE ID = 1;
SELECT @isFinished;