2016-07-11 2 views
1

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

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 запрос все, кажется, работает нормально. он дает сигнал «недостаточно материалов» IF @retVal<=Quantity и записи не записываются (работает так, как должно быть) ... Но когда я вызываю эту процедуру из PHP, она просто не дает никакой ошибки. ни одна из строк не будут вставлены, но я не могу получить уведомление о том, что oppreration не удалось ... вот PHP код:

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

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

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

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

Try параметры прохождения INT как INT, а не строки, т.е. удалить одиночные кавычки чисел, которые делают то текстовые поля – RiggsFolly

+0

Кто написал это состояние сигнала для этих двух условий. PHP может обрабатывать его как любое исключение try/catch. – Drew

+0

Возможный дубликат [Откат MySQL в обработчике] (http://stackoverflow.com/questions/35241571/mysql-rollback-in-handler) – Drew

ответ

0

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

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->sqlstate45000 и проверить, есть ли ошибка в процедуре

0

Mysqli не бросает исключения, вы должны сделать по старинке

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

Также шестые паров десятичные (10,2) не ИНТ номер, который вы передаете не соответствует тому, который, если 10,2 я rememebr правильно означает 8 цифр перед десятичной точкой и 2 после, поэтому постарайтесь номер, который подходит как

$result = $mysqli->query("CALL InsertAction(6, 1, 2, 0, 13, 4312432.41, 1, 0)"); 
Смежные вопросы