2

賃貸物件のサイトを作っています。現在、検索ビットを実行しており、各プロパティに対して呼び出すことができる関数をセットアップしようとしています。この関数はrental_periods、特定のプロパティに関連付けられたテーブルからすべての行を取得し、最適な (最も安い) 週間価格を計算する必要があります。

私はすでに次のテーブルをセットアップしています。

properties- プロパティごとに 1 行

rental_periods- ID で結び付けられた各プロパティの複数の行。

各行はselfcateredまたはcateredです。

selfcateredで与えられた価格から価格を算出する必要がある場合:

  • WeekDayPerDay -wdpd
  • 毎晩の週末 -wepn
  • 月額料金 -monthly
  • 週の価格 -wk

catered価格を指定できる場合:

  • 1 人 1 泊あたり -pppn
  • 一泊 -pn
  • PerPersonPerWeek -pppw

プロパティ ID を取得し、適用されるすべての期間を取得する関数が必要です。次に、セルフケータリング/ケータリングに応じて、最適な週あたりの価格を計算します。

私がこれまでに得たものは機能していないようです。NULL を返すか、100000.00 (私の上限デフォルト価格) を返します。

これがコードです

DELIMITER $$


CREATE FUNCTION get_price(myid INT)
  RETURNS VARCHAR(20)

BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE price decimal(30,3) default 100000.000;

    DECLARE id INT;
    DECLARE prop_id INT;
    DECLARE type enum('catered','selfcatered');
    DECLARE name varchar(45);

    DECLARE `from` date;
    DECLARE `to` date;

    DECLARE currency varchar(45);
    DECLARE so tinyint;
    DECLARE wk decimal(30,3);
    DECLARE wepn  decimal(30,3);

    DECLARE wdpd  decimal(30,3);
    DECLARE monthly  decimal(30,3);
    DECLARE extra  decimal(30,3);
    DECLARE pppn  decimal(30,3);
    DECLARE pn  decimal(30,3);

    DECLARE pppw  decimal(30,3);
    DECLARE minstay int;
    DECLARE maxstay int;
    DECLARE breakfast varchar(45);  
    DECLARE annual TINYINT;

    DECLARE cur1 CURSOR FOR SELECT * FROM rental_periods WHERE prop_id = myid;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    OPEN cur1;

    REPEAT
    FETCH cur1 INTO id, prop_id, type, name, `from`, `to`, currency, so, wk, wepn, wdpd, minstay, maxstay, monthly, extra, pppn, pn, pppw, breakfast, annual;

    IF NOT done THEN
        IF (@type = "selfcatered") THEN
            IF (@wdpd > 0 AND (@wdpd * 7) < @price) THEN
                SET price = @wdpd * 7;
            END IF;

            IF (@wepn > 0 AND (@wepn * 7) < @price) THEN
                SET price = @wepn * 7;
            END IF;

            IF ((@wdpd > 0 AND @wepn > 0) AND
            (@wdpd * 5 + @wepn * 2) < @price) THEN
                SET price = @wdpd * 5 + @wepn * 2;
            END IF;

            IF (@monthly > 0 AND (@monthly / (52 / 12)) < @price) THEN
                SET price = @monthly / (52 / 12);
            END IF;

            IF (@wk > 0 AND @wk < @price) THEN
                SET price = @wk;
            END IF;
        ELSE
            IF (@pppn > 0 AND (@pppn * 7) < @price) THEN
                SET price = @pppn * 7;
            END IF;

            IF (@pn > 0 AND (@pn * 7) < @price) THEN
                SET price = @pn * 7;
            END IF;

            IF (@pppw > 0 AND (@pppw) < @price) THEN
                SET price = @pppw;
            END IF;
        END IF;
    END IF;
    UNTIL done END REPEAT;

    CLOSE cur1;

    RETURN price;
END $$

私はそれが私がそれをどのように整理したか、または純粋なMySQLの欠如に愚かなことであることを望んでいます/そうではありません。

どんな助けでも非常に役に立ちます。

編集:

からの行の例を次に示しrental_periodsます。

INSERT INTO `rental_periods` (`id`, `prop_id`, `type`, `name`, `from`, `to`, `currency`, `so`, `wk`, `wepn`, `wdpd`, `minstay`, `maxstay`, `monthly`, `extra`, `pppn`, `pn`, `pppw`, `breakfast`, `annual`) 
VALUES (64732, 32, 'selfcatered', 'Summer', '2012-06-01', '2012-08-31', NULL, 1, '350', '60', '100', '', '', '', '', NULL, NULL, NULL, NULL, 0);

350関数が週ごとの列から選択されて返されることを期待しています。ただし、wepn60 ではなく 30 だった場合は、210戻ってくると思います (7 * wepn 価格から算出)。

SPでテストしているコード:

DELIMITER $$


CREATE procedure tmp_get_price(myid INT)

 BEGIN

    DECLARE done INT DEFAULT 0;


    DECLARE price decimal(30,3) default 100000.000;


    DECLARE id INT;
    DECLARE prop_id INT;
    DECLARE type enum('catered','selfcatered');
    DECLARE name varchar(45);

    DECLARE `from` date;
    DECLARE `to` date;

    DECLARE currency varchar(45);
    DECLARE so tinyint;
    DECLARE wk decimal(30,3);
    DECLARE wepn  decimal(30,3);

    DECLARE wdpd  decimal(30,3);
    DECLARE monthly  decimal(30,3);
    DECLARE extra  decimal(30,3);
    DECLARE pppn  decimal(30,3);
    DECLARE pn  decimal(30,3);

    DECLARE pppw  decimal(30,3);
    DECLARE minstay int;
    DECLARE maxstay int;
    DECLARE breakfast varchar(45);  
    DECLARE annual TINYINT;



    DECLARE cur1 CURSOR FOR SELECT id, prop_id, type, name, `from`, `to`, currency, so, wk, wepn, wdpd, minstay, maxstay, monthly, extra, pppn, pn, pppw, breakfast, annual FROM rental_periods WHERE prop_id = myid;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    OPEN cur1;


    REPEAT
    FETCH cur1 INTO id, prop_id, type, name, `from`, `to`, currency, so, wk, wepn, wdpd, minstay, maxstay, monthly, extra, pppn, pn, pppw, breakfast, annual;


    IF NOT done THEN
    IF (type = "selfcatered") THEN

        IF (wdpd > 0 AND (wdpd * 7) < price) THEN
            SET price = wdpd * 7;
        END IF;


        IF (wepn > 0 AND (wepn * 7) < price) THEN
            SET price = wepn * 7;
        END IF;


        IF ((wdpd > 0 AND wepn > 0) AND
            (wdpd * 5 + wepn * 2) < price) THEN
            SET price = wdpd * 5 + wepn * 2;
        END IF;


        IF (monthly > 0 AND (monthly / (52 / 12)) < price) THEN
            SET price = monthly / (52 / 12);
        END IF;


        IF (wk > 0 AND wk < price) THEN
            SET price = wk;
        END IF;
    ELSE
        IF (pppn > 0 AND (pppn * 7) < price) THEN
            SET price = pppn * 7;
        END IF;

        IF (pn > 0 AND (pn * 7) < price) THEN
            SET price = pn * 7;
        END IF;

        IF (pppw > 0 AND (pppw) < price) THEN
            SET price = pppw;
        END IF;
    END IF;


    END IF;
    UNTIL done END REPEAT;

    CLOSE cur1;

    select price;
END $$

まだ機能しません... :(私は愚かですか...なぜこれが機能しないのかわかりません..?!?期間を取得します...それぞれを通過します...価格が設定されていない場合....価格を選択....?!?

複数の選択を入れた場合...たとえばカーソル内。一番下のものだけが発火して 100000.000 を返します

すべての値フィールドを小数として設定し、NULL を許可していません...

私が間違っているときの考えはありますか...?ログテーブルに挿入してデバッグも試みました...決して起動しません..?!

4

1 に答える 1

0

カーソルの詳細を読む必要がありますこの継ぎ目は開始するのに適した場所です...

http://www.kbedell.com/2009/03/02/a-simple-example-of-a-mysql-stored-procedure-that-uses-a-cursor/

于 2012-06-01T14:37:25.130 に答える