2

我正在建立一个物业出租网站。我现在正在做搜索,我正在尝试设置一个可以为每个属性调用的函数。该函数需要从附加到给定属性的表中获取所有行,rental_periods然后计算出最佳(最便宜)的每周价格。

我已经设置了以下表格。

properties- 每个属性一行

rental_periods- 每个属性的多行,与 id 绑定。

每行是selfcateredcatered

如果selfcatered需要根据以下给出的价格计算价格:

  • WeekDayPerDay -wdpd
  • 周末每晚 -wepn
  • 每月价格 -monthly
  • 周价 -wk

如果catered可以给出价格:

  • 每人每晚 -pppn
  • 每晚 -pn
  • 每人每周 -pppw

我需要一个函数,它需要一个属性 id,然后获取所有适用的期间,然后根据 selfcated/catered 计算出最好的每周价格。

到目前为止,我所拥有的似乎不起作用。它要么返回 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是 30,而不是 60,我希望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 回答