mysql — mysqli сигнал об ошибке php

У меня есть хранимая процедура Mysql, которая в некоторых случаях выдает ошибку сигнала, например:

    CREATE DEFINER=`root`@`localhost` PROCEDURE `InsertAction`(IN `EmployerID` INT, IN `StoreFromID` INT, IN `StoreToID` INT, IN `StoreID` INT, IN `ProductID` INT, IN `Quantity` DECIMAL(10,2), IN `DualOperation` TINYINT, IN `inOrOut` TINYINT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
START TRANSACTION;
SELECT @lastActionID;
SELECT @lastTransferID;
SELECT @retval;
SELECT SUM(ad.Quantity) INTO @retVal FROM productin pri JOIN actiondetails ad ON ad.ID=pri.ID;
IF DualOperation = 1
THEN
IF @retVal>Quantity
THEN
INSERT INTO Actions (EmployerID, StorehouseID, `Date`)
VALUES (EmployerID, StoreFromID, CURDATE());
SET @lastActionID = (SELECT ID FROM Actions ORDER BY ID DESC LIMIT 1);
INSERT INTO ProductTransfer (ID, TransferType)
VALUES (@lastActionID, 0);

INSERT INTO ActionDetails (ID,ProductID, Quantity)
VALUES (@lastActionID, ProductID, Quantity);

SET @lastTransferID = (SELECT ID FROM ProductTransfer ORDER BY ID DESC LIMIT 1);
INSERT INTO Actions (EmployerID, StorehouseID, `Date`) VALUES (EmployerID, StoreToID, CURDATE());
SET @lastActionID = (SELECT ID FROM Actions ORDER BY ID DESC LIMIT 1);
INSERT INTO ProductTransfer (ID, TransferType, ParentID) VALUES (@lastActionID, 1, @lastTransferID);

INSERT INTO ActionDetails (ID,ProductID, Quantity)
VALUES (@lastActionID, ProductID, Quantity);
ELSE
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Not enough materials';
END IF;
ELSE
INSERT INTO Actions (EmployerID, StorehouseID, `Date`)
VALUES (EmployerID, StoreID, CURDATE());
SET @lastActionID = (SELECT ID FROM Actions ORDER BY ID DESC LIMIT 1);
INSERT INTO ActionDetails (ID, ProductID, Quantity)
VALUES (@lastActionID, ProductID, Quantity);
IF InOrOut = 0
THEN
INSERT INTO ProductIn (ID, OrganizationID) values (@lastActionID, NULL);
ELSE
IF @retVal>Quantity
THEN
INSERT INTO ProductOut (ID, OrganizationID) values (@lastActionID, NULL);
ELSE
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Not enough materials';
END IF;
END IF;
END IF;
COMMIT;
END

Когда я запускаю этот код через Mysql-запрос, кажется, все работает нормально. дает сигнал «недостаточно материалов», ЕСЛИ @retVal<=Quantity и никакие записи не вставляются (работает так, как должно быть) …
Но когда я вызываю эту процедуру из PHP, она просто не дает никакой ошибки. ни одна из строк не вставлена, но я не могу получить уведомление о том, что произошел сбой … вот код php:

$mysqli->query("CALL `InsertAction`('6', '1', '2', '0', '13', '431243241', '1', '0')");

the $mysqli->sqlstate дает 0000,
Как я должен понять, что процедура была сделана или получил сигнал?

так что я действительно хочу, если @retVal<=Quantity тогда дайте php исключение. и этот код печатает "string" из:

try {
$mysqli->query("CALL `InsertAction`(6, 1, 2, 0, 13, 431243241, 1, 0)");
}
catch (Exception $e){
echo "string";
}

1

Решение

MYSQLI не выдает исключений, которые вы должны делать по старинке

$result = $mysqli->query("CALL InsertAction(6, 1, 2, 0, 13, 431243241, 1, 0)");
if ($result === false) {
echo $mysqli->error;
exit;
}

Кроме того, 6-й параметр — это десятичное число (10,2), а не int, число, которое вы передаете, не соответствует 10,2, что, если я правильно помню, означает 8 цифр перед десятичным знаком и 2 после, поэтому попробуйте число, которое подходит как

 $result = $mysqli->query("CALL InsertAction(6, 1, 2, 0, 13, 4312432.41, 1, 0)");
0

Другие решения

Настоящая проблема в приведенном выше коде состоит в том, что переменные не объявлены. поэтому я изменил этот оператор Select для объявления операторов.

BEGIN
DECLARE lastActionID INT unsigned;
DECLARE lastTransferID INT unsigned;
DECLARE retval INT unsigned;
START TRANSACTION;
SELECT SUM(ad.Quantity) INTO retVal FROM productin pri JOIN actiondetails ad ON ad.ID=pri.ID;
IF DualOperation = 1
THEN
IF retVal>Quantity
THEN
INSERT INTO Actions (EmployerID, StorehouseID, `Date`)
VALUES (EmployerID, StoreFromID, CURDATE());
SET lastActionID = (SELECT ID FROM Actions ORDER BY ID DESC LIMIT 1);
INSERT INTO ProductTransfer (ID, TransferType)
VALUES (lastActionID, 0);

INSERT INTO ActionDetails (ID, ProductID, Quantity)
VALUES (lastActionID, ProductID, Quantity);

SET lastTransferID = (SELECT ID FROM ProductTransfer ORDER BY ID DESC LIMIT 1);
INSERT INTO Actions (EmployerID, StorehouseID, `Date`) VALUES (EmployerID, StoreToID, CURDATE());
SET lastActionID = (SELECT ID FROM Actions ORDER BY ID DESC LIMIT 1);
INSERT INTO ProductTransfer (ID, TransferType, ParentID) VALUES (lastActionID, 1, lastTransferID);

INSERT INTO ActionDetails (ID,ProductID, Quantity)
VALUES (lastActionID, ProductID, Quantity);
ELSE
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Not enough materials';
END IF;
ELSE
INSERT INTO Actions (EmployerID, StorehouseID, `Date`)
VALUES (EmployerID, StoreID, CURDATE());
SET @lastActionID = (SELECT ID FROM Actions ORDER BY ID DESC LIMIT 1);
INSERT INTO ActionDetails (ID, ProductID, Quantity)
VALUES (lastActionID, ProductID, Quantity);
IF InOrOut = 0
THEN
INSERT INTO ProductIn (ID, OrganizationID) values (lastActionID, NULL);
ELSE
IF retVal>Quantity
THEN
INSERT INTO ProductOut (ID, OrganizationID) values (lastActionID, NULL);
ELSE
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Not enough materials';
END IF;
END IF;
END IF;
COMMIT;
select true;
END

теперь я могу получить $mysqli->sqlstate 45000 и проверьте, не было ли ошибки в процедуре

0

На самом деле вам нужно подготовиться к тому, чтобы ловить исключения из MySql в PHP.

Использование:

$driver = new mysqli_driver();
$driver->report_mode = MYSQLI_REPORT_ALL ^ MYSQLI_REPORT_INDEX;
0
По вопросам рекламы [email protected]