PHP / MySQL价格矩阵形式验证


PHP / MySQL price matrix form validation

我确定解决方案相当简单,但是我的大脑今天似乎处于正确的精神状态。我有一个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

这不应该被允许,因为在这种情况下,如果用户选择购买三件而不是两件,每件商品的价格都会上涨。因此,我需要确保输入的价格随着数据库中已有值的数量增加而减少。

$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){
        }
    }
}

如果我还没有说得足够清楚,请说。任何帮助将不胜感激。

这可以通过一个简单的函数来完成:

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(被视为 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;
}

请让我知道这是否也有效。

对于此类数据验证,您可能应该使用触发器,在操作完成之前对无效数据引发错误(例如,通过调用不存在的过程); 因此,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

我会反过来做。它将处理给定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