0

我需要帮助才能让这段交易代码按预期工作。看来我没有正确放置 BEGIN 和 COMMIT 。每当增加/减少金额时,余额应增加/减少,但事实并非如此。

<?php
require_once 'login.php';
$db_server = mysql_connect($db_hostname, $db_username, $db_password);
if (!$db_server) die("Unable to connect to MySQL: " . mysql_error());
mysql_select_db($db_database, $db_server)
or die("Unable to select database: " . mysql_error());

if(isset($_POST['amount']))
{
    if(isset($_POST['ADD']) && $number !="")  
    {
          mysql_query("BEGIN"); 
          $query="UPDATE accounts SET balance=balance+amount WHERE number='12345'"; 
    }
    else
    {
          $query="UPDATE accounts SET balance='balance-amount' WHERE number='12345'";
          mysql_query($query);     
    }

  if($query){
     mysql_query("COMMIT");
  }
  else{
    mysql_query("ROLLBACK");
  }

}

echo <<<_END
<form action='transaction.php' method="post"><pre>
Enter the amount: <input type="text" name="amount" />
<input type="submit" value="ADD VALUE" />   <input type="submit" value="SUBTRACT VALUE" />
</pre></form>
_END;

$query="SELECT balance FROM accounts WHERE number='12345'";
$result=mysql_query($query);
$rows=mysql_num_rows($result);

for($j=0; $j<$rows; ++$j)
{ 
   $row=mysql_fetch_row($result);
echo <<<_END
   <pre>
Your current balance is $row[$j]
   </pre>
_END;

}


echo <<<_END
<form action="transaction.php" method="post">
<input type="hidden" name="ADD" value="yes" />
<input type="hidden" name="SUBTRACT" value="yes" />
</pre></form>
_END;

mysql_close($db_server);

 ?>

我究竟做错了什么?

4

2 回答 2

2

你的代码很丑陋,而且不好。例如,您没有amount在查询中设置,如果您发布ADD什么都不会发生,如果不是ADD,代码'balance-amount'不正常balance-$amount$number没有在任何地方设置,等等......

请尝试使用 PDO,因为mysql_*不推荐使用功能...

$db = new PDO('mysql:host='.$db_hostname.';dbname='.$db_database, $db_username, $db_password, array(PDO::ATTR_EMULATE_PREPARES => false));

if(isset($_POST['amount']) && ($_POST['amount'] != '') && ($_POST['number'] != '')){

    if($_POST['type'] == 'ADD')  {
        $query = "UPDATE `accounts` SET `balance`=`balance`+:amount WHERE `number`=:number"; 
    } else {
        $query = "UPDATE `accounts` SET `balance`=`balance`-:amount WHERE `number`=:number";
    }

    try {

        $db->beginTransaction();

        $stmt = $db->prepare($query);
        $stmt->execute(array(':amount' => $_POST['amount'], ':number' => $_POST['number']));

        $db->commit();

    } catch(PDOException $ex) {
        $db->rollBack();
        echo $ex->getMessage();
    }
}

另一个错误出现在您的表单中,您没有发送任何内容,请尝试以下操作:

echo <<<_END
<form action='transaction.php' method="post"><pre>
Enter the amount: <input type="text" name="amount" /> <br />
Number: <input type="text" name="number" value="12345" /><br />
Type: <select name="type"><option value="ADD">ADD</option><option value="SUBSTRACT">SUBSTRACT</option></select>
<input type="submit" value="Make changes" />
</pre></form>
_END;

并获取信息:

$stmt = $db->query(SELECT `balance` FROM `accounts` WHERE `number`='12345');
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo "<pre>Your current balance is ".$row['balance']."</pre>";
于 2012-08-26T19:48:50.087 回答
1

查看分配和执行的顺序:

  • 如果设置了 ADD,则执行 BEGIN,创建一个查询字符串,但从不执行它。
  • 如果未设置 ADD,则不执行 BEGIN,但会创建并执行查询。

两者都有些错误。在所有情况下,$query设置为让您始终 ROLLBACK,但您并不总是启动事务。

你需要更多类似的东西:

if (isset($_POST['amount']))
{
    mysql_query("BEGIN"); 
    if (isset($_POST['ADD']) && $number !="")  
    {
        $query="UPDATE accounts SET balance=balance+amount WHERE number='12345'"; 
    }
    else
    {
        $query="UPDATE accounts SET balance='balance-amount' WHERE number='12345'";
    }
    mysql_query($query);     

    if (...query succeeded...)
    {
        mysql_query("COMMIT");
    }
    else
    {
        mysql_query("ROLLBACK");
    }
}

我不确定您是如何检测到该查询有效的;您可能需要捕获并检查mysql_query().

在某些时候,您将不得不重新考虑在设置 ADD 时从余额中减去金额但数字是空字符串的事实。但是您还需要同时修复重复'12345'的问题。如果未设置数字,您可能不应该在数据库中执行任何操作;您应该完全拒绝该请求。


PS:我认为这些mysql_*功能已被弃用。请改用 PDO。

记住要避免SQL 注入mysql_*——使用函数比使用 PDO更难做到这一点。

于 2012-08-26T19:47:44.063 回答