賃貸物件のサイトを作っています。現在、検索ビットを実行しており、各プロパティに対して呼び出すことができる関数をセットアップしようとしています。この関数は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
関数が週ごとの列から選択されて返されることを期待しています。ただし、wepn
60 ではなく 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 を許可していません...
私が間違っているときの考えはありますか...?ログテーブルに挿入してデバッグも試みました...決して起動しません..?!