0

解決策はかなり単純だと確信していますが、私の脳は今日、正しい心の状態にあるようには見えません。製品の価格マトリックスを格納するMySQLテーブルがあります。

ID     PRODUCT     MINIMUM     PRICE
1      1           2           15
2      1           4           12
3      1           6           10

つまり、IDが1の商品の場合、顧客が買い物かごに最低数量2を持っている場合、各商品の価格は15ポンドまで下がって購入されます。その後、ユーザーがさらに2つの製品をバスケットに入れると、それぞれの価格が£12に引き下げられます。

問題:新しい価格階層が追加されるたびに検証する方法が必要です。したがって、誰かが次の新しい層を追加したい場合:

ID     PRODUCT     MINIMUM     PRICE
4      1           3           16

この場合、ユーザーが2つではなく3つのアイテムを購入することを選択すると、各アイテムの価格が上がるため、これは許可されるべきではありません。したがって、データベースにすでに存在する値に基づいて数量が増加するにつれて、入力された価格が減少していることを確認する必要があります。

$query = 'select id,minimum,price from `cat.tier_price` where product = %d order by minimum asc;';
$query = sprintf($query, (int)$identity);
if(!$return = $db->query($query)){
    echo 'MySQL error!';
}else{
    $quantity = $_POST['quantity'];
    $price = $_POST['quantity'];

    if($return->num_row){
        while($tier = $return->fetch_object){

        }
    }
}

私がこれを十分に明確にしていない場合は、言ってください。どんな助けでも大歓迎です。

4

3 に答える 3

0

この種のデータ検証では、操作が完了する前に、無効なデータに対してエラーを発生させるトリガーを使用する必要があります(たとえば、存在しないプロシージャを呼び出すことによって)。そのため、MySQLは無効なデータを挿入する試みをすべて中止します。

DELIMITER ;;

CREATE TRIGGER foo BEFORE INSERT ON tier_price FOR EACH ROW
  IF (
    SELECT COUNT(*)
    FROM   tier_price
    WHERE  product = NEW.product
       AND (
              (minimum > NEW.minimum AND price > NEW.price)
           OR (minimum < NEW.minimum AND price < NEW.price)
       )
  ) > 0 THEN
    CALL raise_error;
  END IF;;

DELIMITER ;

のレコードtier_priceも更新される可能性がある場合は、同様のトリガーBEFORE UPDATEも必要になる可能性があります。

于 2012-05-10T10:14:56.740 に答える
0

これは、単純な関数で実行できます。

function validateTier($productId, $minimum, $price) {
    // check if the new tier is not higher price for higher minimum
    $query = 'SELECT 1 AS exists FROM `cat.tier_price` WHERE `product` = {$productId} AND `minimum` < {$minimum} AND `price` > {$price} ORDER BY `minimum` DESC LIMIT 1';
    $res = mysql_query($query);
    $result = mysql_fetch_assoc($res);

    if(isset($result['exists']) && $result['exists']) {
        // check if the new tier is not lower price for lower minimum
        $query = 'SELECT 1 AS exists FROM `cat.tier_price` WHERE `product` = {$productId} AND `minimum` > {$minimum} AND `price` < {$price} ORDER BY `minimum` ASC LIMIT 1';
        $res2 = mysql_query($query);
        $result2 = mysql_fetch_assoc($res2);

        if(isset($result2['exists']) && $result2['exists']) return true;
    }

    return false;
}

その後、新しい層を追加する必要があるときはいつでも、この関数を呼び出します。この関数は、最小値が挿入されているレコードよりも低く、価格が挿入されているレコードよりも高いレコードを1つだけ選択しようとします。このクエリが成功すると、1(trueと見なされます)が返されます。これは、新しいティアが挿入される可能性があることを意味します。それ以外の場合はFALSEが返されます。これは、新しい層が正しくないことを意味します。

しかし、これもトリックを行う必要があると思います(そしてもっと簡単です):

function validateTier($productId, $minimum, $price) {
    // check if the new tier is not higher price for higher minimum
    $query = 'SELECT 1 AS exists FROM `cat.tier_price` WHERE `product` = {$productId} AND ((`minimum` < {$minimum} AND `price` > {$price}) OR (`minimum` > {$minimum} AND `price` < {$price})) LIMIT 1';
    $res = mysql_query($query);
    $result = mysql_fetch_assoc($res);

    if(isset($result['exists']) && $result['exists']) return true;

    return false;
}

これでもうまくいくかどうか教えてください。

于 2012-05-10T10:15:45.963 に答える
0

私はそれを逆にしたでしょう。特定のproduct_idのprice_matrixテーブルにエントリがない場合を処理します。

    set @product_id := 1;
    set @minimum :=3;
    set @price :=16;

    select count(*) as count from price_matrix where product_id = @product_id and 
    (
        ( minimum > @minimum and price > @price )
        or 
        ( minimum < @minimum and price < @price ) 
    )

   If count > 0:
       This entry is not permitted
   else :
       Permitted
于 2012-05-10T10:46:06.807 に答える