2012-06-01 236 views
2

我正在構建一個網站的房地產租金。我現在正在進行搜索,我試圖設置一個函數,我可以爲每個屬性調用。該功能需要抓取連接到給定屬性的rental_periods表中的所有行,然後計算出最佳(最便宜)的每週價格。MYSQL - 函數不返回預期結果

我已經設置了下列表格。多行每個屬性,與ID並列 -

properties - 每個屬性

rental_periods一行。

每行是selfcateredcateredwdpd

  • WeekEndPerNight - - wepn
  • 每月價格 - monthly
  • 周價格 - wk
    • WeekDayPerDay:

      如果selfcatered價格需要在給定的價格來制定

      如果catered價格可以在給定的:

      • PerPersonPerNight - pppn
      • PerNight - 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是30,而不是60,我期望210回來(從7 * wepn價格計算)。

      在SP代碼IM測試:

      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 $$ 
      

      仍然不工作... :(我是不是傻了無法看到爲什麼這不會工作.. 得到時期..?!? 。 去throught每一個... 如果價格更低設置.... 選擇價格....?!?

      ,如果我把多選擇在...例如光標內。 只有最下面的一個火災和返回100000.000

      我設置的所有值字段,小數和不允許空...

      任何想法,當我去錯了...?也嘗試通過插入到日誌表中進行調試...從來沒有觸發..?!

    +1

    當我在搞清楚我的存儲過程所走的路徑問題,我加上'PRINT(1 ,2,3等)在控制流程中的語句,以及一路打印出某些變量的值。這可能有助於未來。 (對於MySQL,您應該可以'SELECT(1,2,3)'。) –

    +0

    檢查以確保光標中的列與您的變量保持一致。您可能想要爲每列指定名稱,而不是使用'select *'。 - >並且做什麼@AdamV說< - – ethrbunny

    +0

    你能給我們一行數據,以及你期望它返回什麼,所以我們可以通過你的程序來看看它爲什麼不匹配? –

    回答

    0

    需要閱讀更多有關遊標這個接縫一個很好的開始...

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

    +0

    計時它... !!!我是一個F88king白癡俯視它...... –

    +1

    'prop_id = myid'使用用戶變量不是prop_id從選擇...放在rental_periods.prop_id中,它按預期工作...... !!!! –

    +0

    在我看來,這必須張貼在你的答案中,並接受答案(就像你正在計劃)。因爲這是有經驗的MySQL開發人員只能*發現的東西。爲了他們的利益,讓我們認爲他們不在身邊。 :) –