Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mysqli信号到php错误_Php_Mysql_Mysqli_Signals - Fatal编程技术网

mysqli信号到php错误

mysqli信号到php错误,php,mysql,mysqli,signals,Php,Mysql,Mysqli,Signals,我有一个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

我有一个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查询运行这段代码时,一切似乎都很正常。如果MYSQLI没有抛出异常,那么它会发出“材料不足”的信号,您必须采用老式的方法

$result = $mysqli->query("CALL InsertAction(6, 1, 2, 0, 13, 431243241, 1, 0)");
if ($result === false) {
    echo $mysqli->error;
    exit;
}
此外,第6个参数是十进制(10,2)而不是整数。您传递的数字与10,2不符,如果我记得10,2的正确含义是小数点前8位,小数点后2位,因此请尝试符合以下条件的数字:

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

MYSQLI不会抛出异常,您必须以老式的方式执行

$result = $mysqli->query("CALL InsertAction(6, 1, 2, 0, 13, 431243241, 1, 0)");
if ($result === false) {
    echo $mysqli->error;
    exit;
}
此外,第6个参数是十进制(10,2)而不是整数。您传递的数字与10,2不符,如果我记得10,2的正确含义是小数点前8位,小数点后2位,因此请尝试符合以下条件的数字:

 $result = $mysqli->query("CALL InsertAction(6, 1, 2, 0, 13, 4312432.41, 1, 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->sqlstate
45000
并检查过程中是否有错误

上面代码中的真正问题是没有声明变量。所以我将这个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->sqlstate
45000
并检查过程中是否有错误

实际上,您需要做一些准备,以便在PHP中捕获MySql的异常

使用:


实际上,您需要做一些准备来捕获PHP中MySql的异常

使用:


尝试将INT参数作为INT而不是字符串传递,即删除数字周围的单引号,使其成为文本字段。无论是谁编写的,这都具有这两种情况的信号状态。PHP可以像处理任何try/catch异常一样处理它。可能重复@RiggsFolly,谢谢您的评论。当然这些数字应该作为数字传递,我的错。“但这并不能解决问题。”德鲁,谢谢你的评论,但这是另一个话题。PHP也不能用try-catch处理它。正如我所提到的,它没有给出任何异常…尝试将INT参数作为INT而不是字符串传递,即删除数字周围的单引号,然后生成文本字段。无论是谁编写的,这都具有这两种情况的信号状态。PHP可以像处理任何try/catch异常一样处理它。可能重复@RiggsFolly,谢谢您的评论。当然这些数字应该作为数字传递,我的错。“但这并不能解决问题。”德鲁,谢谢你的评论,但这是另一个话题。PHP也不能用try-catch处理它。正如我提到的,它没有给任何例外。。。