PHP / MySQL价格矩阵表格验证

时间:2012-05-10 10:04:24

标签: php mysql validation mysqli

我确信解决方案相当简单,但我的大脑今天似乎并没有处于正确的心态。我有一个存储我产品定价矩阵的MySQL表。

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

快速解释一下,对于ID为1的产品,如果顾客在购物篮中的最小数量为2,则每件商品的价格将降至15英镑。如果用户随后将另外两种产品放入其购物篮中,则每种产品的价格将降至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){

        }
    }
}

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

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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(视为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;
}

请告诉我这是否也有效。

答案 2 :(得分: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