MYSQL - 函数未返回预期结果

时间:2012-06-01 12:45:01

标签: mysql sql database

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

我已经设置了以下表格。

properties - 每个属性一行

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

每一行都是selfcateredcatered

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

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

如果catered价格可以在:

中给出
  • PerPersonPerNight - pppn
  • PerNight - pn
  • PerPersonPerWeek - pppw

我需要一个带有属性ID的函数,然后抓取所有适用的句点,然后根据selfcatered / 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 ...

当我出错时的任何想法......?也通过插入日志表尝试调试...永远不会触发..?!

1 个答案:

答案 0 :(得分:0)

需要阅读有关游标的更多信息,这是一个开始的好地方......

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