2012-05-10 1 views
0

ソリューションはかなりシンプルですが、私の脳は今日は正しい状態には見えません。私は私の製品の価格マトリックスを格納するMySQLテーブルを持っています。PHP/MySQLの価格マトリックスフォームの妥当性確認

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

顧客が買い物かご2の最小量を持っているのであれば迅速な説明は、IDが1の製品のために、各アイテムの価格は£15まで買っています。ユーザーが別の2つの商品を入れた場合、それぞれの価格は£12に引き下げられます。

問題:追加するたびに新しい価格層を検証する方法が必要です。誰かが新しい階層を追加したいのであれば:

ID  PRODUCT  MINIMUM  PRICE 
4  1   3   16 

ユーザーは三つの項目ではなく、2を購入することを選択した場合、この場合、各アイテムの価格が増加するので、これは許されるべきではありません。だから私は、すでにデータベースにある値に基づいて数量が増えるにつれて、入力された価格が減少していることを保証する必要があります。

$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

[分を検証する場合は、 3]既存の最小値を3(ここでは2)より低くし、与えられた価格がここに関連する値よりも小さいかどうかを確認します。 2(= 15) – djot

答えて

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(真と見なされます)が返され、これは新しい裂傷が挿入される可能性があることを意味します。さもなければ、新しい層が不正確であることを意味する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; 
} 

、これも動作するかどうか私に教えてください。

+0

これはうれしいことですが、これは "3,16"で動作します。しかし、私が "3,11"を試しても、これは許可されてはいけません。価格は最低4品目の価格よりも低くなっていますか?謝罪私はこれを私の間違いだと言及しなかった。 – Adam

+0

@Adam私は、この機能を編集しました。今では、最低価格で下位の価格が既に階層に入っているものよりも低くないようにしてはいけません。 – shadyyx

+0

皆様にありがとうございます。私の脳は少し暖まっていて、とても感謝しています。 – Adam

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をお勧めします。

+0

これは前に使用していない面白いアプローチです。私は現在、エラーが発生しています: トリガーから結果セットを返すことはできません。 – Adam

+0

@Adam:これは、過度に最適化しようとして教えてくれるでしょう。上記のロールバック版を参照してください。 – eggyal

+0

皆様に感謝します。私はこのような華麗な質問を一度も見たことがありません。私の脳は少し暖まっていて、とても感謝しています。 – Adam

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 
+0

皆様にありがとうございます。私は決してこのような素晴らしい回答を見たことはありません。私の脳は少し暖まっていて、とても感謝しています。 – Adam