我确信解决方案相当简单,但我的大脑今天似乎并没有处于正确的心态。我有一个存储我产品定价矩阵的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){
}
}
}
如果我没有说清楚,请说。任何帮助将不胜感激。
答案 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