我正在尝试通过php运行mysqli查询,该查询将根据所选内容更新项目的数量。因此,如果用户选择两个数量的项目,那么该数量应该减少两个。我可以成功地执行此操作而无需使用此代码:
$postparts = $_POST['part_name']; <-- This is an array of the items chosen
$postqty = $_POST['qty']; <-- This is an array of the qty of each item chosen
$combine = array_combine($postparts, $postqty); <-- I combine the arrays to match the qty to the item that was chosen.
foreach ($combine as $part=>$qty)
{
$update = <<<SQL
UPDATE `Houston` SET `qty` = (`qty`-?) WHERE `partnumber` = ?;
SQL;
$result = $mysqli->prepare($update);
$result->bind_param("is", $qty, $part);
$result->execute();
}
上面的代码会从所选项目中减去相应的数量 - 这里没有问题。但是,我需要实施一个额外的检查,这样如果两个人同时检查同一个项目,第一个会得到一个成功的结果,但如果该项目的数量因为第一个结账流程那么为0 ,第二个人会失败。我试着这样做:
$postparts = $_POST['part_name'];
$postqty = $_POST['qty'];
$partarray = array();
foreach ($postparts as $part => $id)
{
$finalpart = ($postparts[$part]);
$stuff = explode(',', $finalpart);
$partarray = array_merge($partarray, $stuff);
}
$combine = array_combine($postparts, $postqty);
$in = implode(',', array_fill(0, count($partarray), '?'));
$check = <<<SQL
SELECT * FROM `Houston` WHERE `partnumber` in ($in);
SQL;
$statcheck = $mysqli->prepare($check);
$statcheck->bind_param(str_repeat('s', count($partarray)), ...$partarray);
$statcheck->execute();
$statcheck->store_result();
$statcheck->bind_result($id, $partcat, $partnumber, $partqty);
while ($statcheck->fetch())
{
if ($partqty > 0)
{
foreach ($combine as $part=>$qty)
{
$update = <<<SQL
UPDATE `Houston` SET `qty` = (`qty`-?) WHERE `partnumber` = ?;
SQL;
$result = $mysqli->prepare($update);
$result->bind_param("is", $qty, $part);
$result->execute();
}
}
if ($partqty == 0)
{
header("location:error.php");
}
}
所以这&#34;几乎&#34;工作 - 除了foreach循环多次运行。假如用户检出两个项目 - 那么foreach循环运行两次 - 因此订购的数量最终会使每个项目加倍(如果有3个项目,则数量增加三倍等)。我怀疑这种行为的原因是因为我在while循环中运行foreach循环,但我不知道如何解决这个问题以使其正常工作。谁知道怎么做?
答案 0 :(得分:0)
您完全不了解准备好的语句。顾名思义,你只需准备一次。
此外,选择数据只是为了更新它没有意义。无论您需要检查什么,都必须通过SQL查询进行检查。
$combine = array_combine($postparts, $postqty);
$sql = "UPDATE Houston SET qty = qty-?) WHERE partnumber=? AND qty > 0";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("is", $qty, $part);
foreach ($combine as $part=>$qty)
{
$stmt->execute();
}
我需要实施一个额外的检查,以便如果两个人同时检查同一个项目,第一个会得到一个成功的结果,但如果该项目的数量因为第一次结账而为0过程中,第二个人会失败。
你需要表锁定。如果你确实需要这样的检查。
要查看更新是否成功,请使用PDOStatement::rowCount()
答案 1 :(得分:-1)
我能够找到一个有效的解决方案,但不确定它是否是最优雅的解决方案。如果有人有更好的主意,请告诉我。
$postparts = $_POST['part_name'];
$postqty = $_POST['qty'];
$combine = array_combine($postparts, $postqty);
$update = <<<SQL
UPDATE `Houston` SET `qty` = (`qty`-?) WHERE `partnumber` = ?;
SQL;
$result = $mysqli->prepare($update);
$result->bind_param("is", $qty, $part);
$check = <<<SQL
SELECT * FROM `Houston` WHERE `partnumber` = ?;
SQL;
$checkpart = $mysqli->prepare($check);
$checkpart->bind_param('s', $part);
foreach ($combine as $part=>$qty)
{
$checkpart->execute();
$checkpart->store_result();
$checkpart->bind_result($id, $partcat, $partnumber, $partqty);
if ($checkpart->fetch())
{
if ($partqty > 0)
{
$result->execute();
}
elseif ($partqty == 0)
{
header("location:error.php");
}
}
}