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

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

$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(视为 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 回答