2012-06-01 4 views
2

Je suis en train de construire un site pour la location de propriétés. Je fais maintenant le bit de recherche et j'essaye de mettre en place une fonction que je peux appeler pour chaque propriété. La fonction doit saisir toutes les lignes de la table rental_periods attachées à une propriété donnée, puis déterminer le meilleur prix hebdomadaire (le moins cher).MYSQL - fonction ne renvoyant pas les résultats attendus

J'ai déjà installé les tables suivantes.

properties - Une ligne pour chaque propriété

rental_periods - lignes multiples pour chaque propriété, à égalité avec id. Les lignes sont selfcatered ou catered.

Si selfcatered le prix doit être élaboré à partir des prix donnés dans:

  • WeekDayPerDay - wdpd
  • WeekEndPerNight - wepn
  • Prix mensuel - monthly
  • Prix de la Semaine - wk

Si catered les prix peuvent être donnés dans:

  • PerPersonPerNight - pppn
  • PerNight - pn
  • PerPersonPerWeek - pppw

je besoin d'une fonction qui prend un identifiant de propriété et saisit alors toutes les périodes cela s'applique, puis en fonction de selfcatered/traiteur fonctionne le prix par semaine qui est le meilleur. Ce que j'ai jusqu'ici ne semble pas fonctionner. Il renvoie NULL ou renvoie 100000.00 (mon prix par défaut de limite supérieure).

est ici le code

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

J'espère/pas des thats c'est quelque chose de stupide avec la façon dont je l'ai arrangé ou mon manque de MySQL pur.

Toute aide serait très utile.

EDIT:

Voici un exemple de ligne de 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); 

Je pense que la fonction renvoie 350 cueillis dans la colonne par semaine. Cependant, si le wepn était 30, pas 60, je m'attendrais à 210 de revenir (calculé à partir de 7 * prix wepn).

Le code test im dans 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 $$ 

fonctionne toujours pas ... :(suis-je stupide ... ne peut pas voir pourquoi cela ne marchera pas .. obtient les périodes ..?!? . va throught chacun ... si le prix est moins le mettre .... sélectionnez prix ....?!?

si je mets les sélections multiples dans ... par exemple à l'intérieur du curseur. seulement le fond du feu tire et renvoie 100000.000

J'ai configuré tous les champs de valeur en tant que décimales et ne permettant pas la valeur NULL ...

des pensées quand je vais mal ...? a également essayé de déboguer en insérant dans la table de journal ... ne tire jamais ..?!

+1

Quand je vais avoir des questions figurant sur le chemin mes procédures stockées prennent, j'ajouter 'IMPRIMER (1 , 2,3, etc) 'dans le flux de contrôle, ainsi que l'impression des valeurs de certaines variables en cours de route. Cela pourrait aider à l'avenir. (Pour MySQL, vous devriez pouvoir 'SELECT (1,2,3)'.) –

+0

Assurez-vous que les colonnes de votre curseur sont alignées avec vos variables. Vous pourriez vouloir nommer chaque colonne au lieu d'utiliser 'select *'. -> et faites ce que @AdamV a dit <- – ethrbunny

+0

Pouvez-vous nous donner un exemple de ligne de données, ainsi que ce que vous attendez de ce retour, afin que nous puissions passer en revue votre procédure et voir pourquoi elle ne correspond pas? –

Répondre

0

besoin de lire plus sur les curseurs ce coud un bon endroit pour commencer ...

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

+0

Clocked it ... !!! Je suis un idiot F88king pour le regarder ... –

+1

Le 'prop_id = myid' utilisait la variable utilisateur pas prop_id de la sélection ... mettre en location_periods.prop_id et cela a fonctionné comme prévu ... !!!! –

+0

À mon avis, cela doit être affiché dans votre réponse et la réponse acceptée (comme prévu). Car c'est quelque chose que les développeurs MySQL expérimentés ont juste * eu * à repérer. Pour leur bien, laissez-nous penser qu'ils n'étaient pas là. :) –

Questions connexes