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

あなたのコードはかなり醜く、OKではありません。たとえば、クエリで設定していない場合、何もamount投稿しない場合、コードが正常でない場合、コードが正しく設定されていない場合、どこにも設定されていない場合など...ADDADD'balance-amount'balance-$amount$number

mysql_*関数は非推奨になっているので、PDOで試してください...

$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は常にロールバックするように設定されていますが、トランザクションを常に開始しているわけではありません。

次のようなものが必要です。

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'ただし、繰り返しを同時に修正する必要もあります。番号が設定されていない場合は、おそらくDBで何もしてはいけません。リクエストを完全に拒否する必要があります。


mysql_*PS:機能は廃止されたと思います。代わりにPDOを使用してください。

SQLインジェクションを避けることを忘れないでください。これはmysql_*、PDOよりも関数で行うのがはるかに困難です。

于 2012-08-26T19:47:44.063 に答える