更新mysql数据库中的记录时出现问题

时间:2013-05-19 11:35:40

标签: mysql

下面是我的代码:

<?php
$response = array();

if ($_POST['code_input'] != ''){
    $code_input = $_POST['code_input'];
    $email_code = $_POST['email_code'];

    $link = mysql_connect('localhost','root','') or die ('Could not connect: '.mysql_error());
    mysql_select_db('ichop') or die ('Could not connect to database');

    //check if redemption code exist
    $exist = mysql_query("select * from redemption where red_code = '$code_input'");

    //check if redemption code is usable
    $usable = mysql_query("select * from redemption where code_status = 'usable' and red_code = '$code_input'");

    //check if users already have the card
    $possess = mysql_query("select * from customer customer join card card on customer.customer_id = card.customer_id join redemption redemption on card.merchant_id = redemption.merchant_id where card.merchant_id = redemption.merchant_id and redemption.red_code = '$code_input'");

    //check if reward name is "reward point"
    $point = mysql_query("SELECT * FROM redemption redemption JOIN reward reward ON redemption.merchant_id = reward.merchant_id WHERE reward.reward_name LIKE  '%point%' AND redemption.red_code =  '$code_input'");
    $data3 = mysql_fetch_array($point);

    $customer = mysql_query("select * from customer where C_email = '$email_code'");
    $data1 = mysql_fetch_array($customer);

    $merchant = mysql_query("select * from redemption where red_code = '$code_input'");
    $data2 = mysql_fetch_array($merchant);

    $card = mysql_query("select redemption.Total_Point, card.card_id from customer customer join card card on customer.customer_id = card.customer_id join redemption redemption on card.merchant_id = redemption.merchant_id where redemption.red_code = '$code_input'");
    $data4 = mysql_fetch_array($card);

    if(mysql_num_rows($exist) == 1){
        if(mysql_num_rows($usable) == 1){
            if(mysql_num_rows($possess) == 1){

            } else {
                //create new card for customer              
                $create = mysql_query("INSERT INTO card (Card_ID, Chop_Amt, Customer_ID, Merchant_ID) VALUES ('', '0', '".$data1["Customer_ID"]."', '".$data2["Merchant_ID"]."')");

                if(mysql_num_rows($point) == 1){
                    //update the chop amount in card details
                    $update1 = mysql_query("UPDATE card SET Chop_Amt = '".$data3["Total_Point"]."' where Customer_ID = '".$data1["Customer_ID"]."' and Merchant_ID = '".$data2["Merchant_ID"]."'");

                    $update2 = mysql_query("UPDATE redemption SET Code_Status = 'Unusable', Red_Date = now(), Point_Balance = '".$data3["Total_Point"]."', Card_ID = '".$data4["Card_ID"]."' where red_code = '$code_input'");

                    $response["success"] = 1;
                    $response["message"] = "Code redeemed!";

                    echo json_encode($response);
                } else {
                    $response["success"] = 0;
                    $response["message"] = "You do not have enough point to use the code!";

                    echo json_encode($response);
                }
            }
        } else {
            //error for non-usable code
            $response["success"] = 0;
            $response["message"] = "Code is not usable!";

            echo json_encode($response);
        }
    } else {
        //error for non existing code
        $response["success"] = 0;
        $response["message"] = "Code does not exist!";

        echo json_encode($response);
    }
} else {
    //error for blank field
    $response["success"] = 0;
    $response["message"] = "Please fill in the code field!";

    echo json_encode($response);
}
?>

我的情况是,如果他们没有1,我希望我的系统在“Card”中创建一条新记录,然后相应地更新“Redemption”表。

但是,我只设法创建了一张新卡,但我无法更新“兑换”表...任何人都可以帮助我吗?请告诉我你需要检查的任何事情......谢谢!

我试过了

$card = mysql_query("select redemption.Total_Point, card.card_id from customer customer 
join card card on customer.customer_id = card.customer_id 
join redemption redemption on card.merchant_id = redemption.merchant_id 
where redemption.red_code = '$code_input'");
$data4 = mysql_fetch_array($card);

在一个单独的php文件中,我可以得到我想要的数据......但是我不明白为什么它没有更新&gt;&lt;

2 个答案:

答案 0 :(得分:0)

没有调试代码 - 单步执行 - 我无法弄清楚发生了什么,但代码结构的方式使得很难遵循逻辑。单个SQL查询没有按照您的预期执行操作,可能导致静默失败,并且存在大量嵌套条件,这使得很难跟上发生的情况。

我觉得你可以更有效地编写更新 - 你从其他查询中获取数据到PHP变量,并将它们传递给更新,你可以通过在update语句中加入那些数据来做到这一点

其次,请考虑“早点破解”。例如:

if ($_POST['code_input'] == ''){
    //error for blank field
    $response["success"] = 0;
    $response["message"] = "Please fill in the code field!";

    die json_encode($response);
}

这会在验证步骤之后立即发送错误,而不是在代码文件的另一端。

接下来,考虑将所有验证/数据检索步骤分解为自己的功能。 因此,请考虑:

,而不是上面的代码
if (!isInputValid($_POST['code_input'])){
    //error for blank field
    $response["success"] = 0;
    $response["message"] = "Please fill in the code field!";

    die json_encode($response);
}
function isInputValid($input){
    if ($input == ''){
       return false;
    }
    return true; 
}

接下来,考虑不依赖于多个MySQL结果集及其奇怪的“返回FALSE或数组”行为。考虑创建一个名为$totalPoints的变量,而不是$data3["Total_Point"]

试试这个,我很确定这个bug会变得明显......

答案 1 :(得分:0)

您应该开始使用PDO而不是mysql_*函数,因为它们已被弃用。此外,您应该对查询更加小心 - 我看到您从同一个表中选择了几乎相同的信息,但只是请求不同的列。例如,可以将这些查询$exist$usable合并到一个查询中,然后使用简单的if/else语句检查查询结果。这将节省一些系统资源,并且可以更快地加载应用程序。

另外,我不明白为什么在别名名称本身与表名相同时,你在sql查询中使用表别名?这些别名适用于您希望缩短表名称的情况(即my_table_name变为mtn,因为它更容易和更快地编写)或者如果您要加入几个包含列的表相同的名称,但不同的含义和用法。

关于你所编写的代码,正如@Neville K指出的那样,很难确定它的错误。你编写它的方式不会使调试变得容易。我花时间使用PDO重新组织您的代码。代码很可能 NOT 立即工作 - 我没有测试它,我没有数据库的结构。您可能需要做一些工作才能使其正常工作。我想建议您使用datadata1data2等变量名来反对。尝试给变量一个有意义的名称,并澄清它所拥有的数据。

以下是代码:

<?php

$response = array();
$code_input = $_POST['code_input'];
$email_code = $_POST['email_code'];

if ($code_input != "" && $email_code != ""){

    // PDO link to database;
    $host = 'localhost';
    $port = 3306;
    $dbname = 'ichop';
    $dbuser = 'PUT_YOUR_DB_USER_HERE';
    $dbpass = 'PUT_YOUR_DB_USER_PASS_HERE';
    $connect_string = "mysql:host=".$host.";port=".$port.";dbname=".$dbname;
    $db = new PDO( $connect_string, $dbuser, $dbpass );
    $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

    // Get the code from the database using a prepared statement (ps in the variables stands for Prepared Statement)
    $rps = $db->prepare('
    SELECT *
    FROM redemption
    WHERE red_code = :code_input');
    // Bind a the value from $code_input to the :code_input variable in the sql code.
    $rps->bindValue(':code_input', $code_input, PDO::PARAM_STR); // If the $code_input is an integer, use PDO::PARAM_INT
    // Execute the query
    $rps->execute();
    // Fetch the results
    // - PDO::FETCH_ASSOC would return an associative array, containing the column names of the table
    //   i.e.
    //   array(
    //      'red_code' => 1234,
    //      'usable' => true
    //      ..........
    //   )
    // For more information visit http://www.php.net/manual/en/pdo.constants.php
    $redemption_code = $rps->fetch(PDO::FETCH_ASSOC);

    // Check if the code exists in the database.
    if($redemption_code != ""){
        // Check if the code is usable
        if($redemption_code['usable'] == 1 && $redemption_code['red_code'] == $code_input) {
            //check if users already have the card
            $pps = $db->prepare('
            SELECT *
            FROM customer
            JOIN card on customer.customer_id = card.customer_id
            JOIN redemption redemption on card.merchant_id = redemption.merchant_id
            WHERE card.merchant_id = redemption.merchant_id
            AND redemption.red_code = :code_input');
            $pps->bindValue(':code_input', $code_input, PDO::PARAM_STR);
            $pps->execute();
            $possessed = $pps->fetch(PDO::FETCH_ASSOC);

            // This card haven't been used yet
            if($possessed == ""){
                // check if reward name is "reward point"
                // I believe this code can be merged with $redemption_code but I don't know your database structure so I'm leaving it as is.
                $point_ps = $db->prepare("
                SELECT *
                FROM redemption redemption
                JOIN reward reward ON redemption.merchant_id = reward.merchant_id
                WHERE reward.reward_name LIKE '%point%'
                AND redemption.red_code = :code_input");
                $point_ps->bindValue(':code_input', $code_input, PDO::PARAM_STR);
                $point_ps->execute();
                $point = $point_ps->fetch(PDO::FETCH_ASSOC);

                // Please check if the column name "C_email" is with a capital C. Do the check for the column names in the other queries as well.
                $customer_ps = $db->prepare('SELECT * FROM customer WHERE C_email');
                $customer_ps->bindValue(':email_code', PDO::PARAM_STR);
                $customer_ps->execute();
                $customer = $customer_ps->fetch(PDO::FETCH_ASSOC);

                // I've got no idea what this is.
                $cdps = $db->prepare("
                SELECT
                    redemption.Total_Point,
                    card.card_id
                FROM customer
                JOIN card ON customer.customer_id = card.customer_id
                JOIN redemption ON card.merchant_id = redemption.merchant_id
                WHERE redemption.red_code = :code_input");
                $cdps->bindValue(':code_input', $code_input, PDO::PARAM_STR);
                $card = $cdps->fetch(PDO::FETCH_ASSOC);

                // Create new card for the customer
                $insert_ps = $db->prepare("INSERT INTO card(Chop_Amt, Customer_ID, Merchant_ID) VALUES ('0', :customer_id, :merchant_id)");
                $insert_ps->bindValue(':customer_id', $customer["Customer_ID"], PDO::PARAM_INT);
                $insert_ps->bindValue(':merchant_id', $redemption_code["Merchant_ID"], PDO::PARAM_INT);
                $insert_ps->execute(); // This will return true on successful insert and false on unsuccessful.

                if($insert_ps) {
                    // If, when executing the code, the redemption & card tables don't get updated
                    // you need to debug the $point variable - see if a record is being returned and
                    // if that's what you need.
                    if($point != ""){
                        $card_update_ps = $db->prepare("UPDATE card SET Chop_Amt = :total_point WHERE Customer_ID = :customer_id AND Merchant_ID = merchant_id");
                        $card_update_ps->bindValue(':customer_id', $customer["Customer_ID"], PDO::PARAM_INT);
                        $card_update_ps->bindValue(':merchant_id', $redemption_code["Merchant_ID"], PDO::PARAM_INT);
                        $card_update_ps->bindValue(':total_point', $point["Total_Point"], PDO::PARAM_INT); // I guess this is an integer?
                        $card_update_ps->execute();

                        $redemption_update_ps = $db->prepare("UPDATE redemption SET Code_Status = 'Unusable', Red_Date = now(), Point_Balance = :total_point, Card_ID = :card_id WHERE red_code = :code_input");
                        $redemption_update_ps->bindValue(':code_input', $code_input, PDO::PARAM_STR);
                        $redemption_update_ps->bindValue(':total_point', $point["Total_Point"], PDO::PARAM_INT);
                        $redemption_update_ps->bindValue(':card_id', $card['Card_ID'], PDO::PARAM_INT);
                        $redemption_update_ps->execute();

                        $response["success"] = 1;
                        $response["message"] = "Code redeemed!";

                        echo json_encode($response);
                    } else {
                        $response["success"] = 0;
                        $response["message"] = "You do not have enough point to use the code!";

                        echo json_encode($response);
                    }
                }
                else {
                    // Print an error if you can't insert the card.
                }
            }
            // This card was used
            else {
                // Print an error?
            }
        }
        else {
            //error for non-usable code
            $response["success"] = 0;
            $response["message"] = "Code is not usable!";
            echo json_encode($response);
        }
    }
    // The redemption code does not exists
    else {
        //error for non existing code
        $response["success"] = 0;
        $response["message"] = "Code does not exist!";

        echo json_encode($response);
    }
} else {
    //error for blank field
    $response["success"] = 0;
    $response["message"] = "Please fill in the code field!";

    echo json_encode($response);
}

?>