mysql过程 - 在条件in子句中解析参数的问题

时间:2016-08-02 13:11:27

标签: mysql stored-procedures

以下是程序

CREATE DEFINER=`root`@`localhost` PROCEDURE `sitter_price`(
   in in_hours float,
   in age varchar(100),
   in no_of_sitters int,
   in no_of_days int
)
BEGIN
  select 
  TRUNCATE(sum(price)*in_hours*no_of_days*no_of_sitters,2) as 
  total_amount 
    from job_prices jp
    join kids_ages ka on ka.id = jp.kids_age_id
where ka.age in(age) and start_hours > in_hours 
    AND in_hours <= end_hours;
END

这个过程中的问题是我将如何传入age varchar(100),参数in,in子句 目前我正在使用查询解析

CALL `usitterz`.`sitter_price`(4.10,'1,2,3,4', 3, 5);

但这是错误的,因为在查询中读取它像('1,2,3,4'),但我希望它像 - (1,2,3,4)。

就像

CREATE DEFINER=`root`@`localhost` PROCEDURE `sitter_price`(
   in in_hours float,
   in age varchar(100),
   in no_of_sitters int,
   in no_of_days int
)
BEGIN
  select 
  TRUNCATE(sum(price)*in_hours*no_of_days*no_of_sitters,2) as 
  total_amount 
    from job_prices jp
    join kids_ages ka on ka.id = jp.kids_age_id
where ka.age in(1,2,3,4) and start_hours > in_hours 
    AND in_hours <= end_hours;
END

3 个答案:

答案 0 :(得分:1)

第1步:乱七八糟地获取EXECUTE

的字符串
DROP PROCEDURE IF EXISTS sitter_price;
DELIMITER $
CREATE DEFINER=`root`@`localhost` PROCEDURE `sitter_price`(
   in in_hours float,
   in age varchar(100),
   in no_of_sitters int,
   in no_of_days int
)
BEGIN
    SET @theSql=CONCAT('SELECT TRUNCATE(sum(price)*',in_hours,'*',no_of_days,'*',no_of_sitters,',2)');
    SET @theSql=CONCAT(@theSql,' as total_amount from job_prices jp join kids_ages ka on ka.id = jp.kids_age_id');
    SET @theSql=CONCAT(@theSql,' where ka.age in(',age,') and start_hours > ',in_hours,' AND ');
    SET @theSql=CONCAT(@theSql,in_hours,'<= end_hours');
    /*
  select 
  TRUNCATE(sum(price)*in_hours*no_of_days*no_of_sitters,2) as 
  total_amount 
    from job_prices jp
    join kids_ages ka on ka.id = jp.kids_age_id
where ka.age in(1,2,3,4) and start_hours > in_hours 
    AND in_hours <= end_hours;
    */
    select @theSql;
END$
DELIMITER ;

Step2:传入参数以查看字符串是什么样的

call sitter_price(89,'1,2,4,8',11,12);

SELECT TRUNCATE(sum(price)*89*12*11,2) as total_amount 
from job_prices jp 
join kids_ages ka on ka.id = jp.kids_age_id 
where ka.age in(1,2,4,8) and start_hours > 89 
AND 89<= end_hours

步骤3:使用PREPAREEXECUTE最终确定存储过程。

DROP PROCEDURE IF EXISTS sitter_price;
DELIMITER $
CREATE DEFINER=`root`@`localhost` PROCEDURE `sitter_price`(
   in in_hours float,
   in age varchar(100),
   in no_of_sitters int,
   in no_of_days int
)
BEGIN
    SET @theSql=CONCAT('SELECT TRUNCATE(sum(price)*',in_hours,'*',no_of_days,'*',no_of_sitters,',2)');
    SET @theSql=CONCAT(@theSql,' as total_amount from job_prices jp join kids_ages ka on ka.id = jp.kids_age_id');
    SET @theSql=CONCAT(@theSql,' where ka.age in(',age,') and start_hours > ',in_hours,' AND ');
    SET @theSql=CONCAT(@theSql,in_hours,'<= end_hours');
    PREPARE stmt from @theSql; -- create a prepared stmt from the above concat
    EXECUTE stmt;   -- run it
    DEALLOCATE PREPARE stmt;    -- cleanup
END$
DELIMITER ;

MySqL手册页SQL Syntax for Prepared Statements

请注意,上述CONCAT()只有使用用户变量(带有@符号)才能成功。不是DECLARE的本地变量。

答案 1 :(得分:0)

以下是我自己的问题的答案

CREATE PROCEDURE `sitter_price`(
   in in_hours float,
   in age varchar(100),
   in no_of_sitters int,
   in no_of_days int
)
BEGIN
 select 
  TRUNCATE(sum(price)*in_hours*no_of_days*no_of_sitters,2) as total_amount
  from job_prices jp
  join kids_ages ka on ka.id = jp.kids_age_id
 where 
  jp.status = 1 and 
  find_in_set(ka.age,age) and
  in_hours between jp.start_hours and jp.end_hours;
END

通话程序

CALL `usitterz`.`sitter_price`(6, '1,2,3,4', 1, 5);

答案 2 :(得分:0)

另一个答案

CREATE DEFINER=`root`@`localhost` PROCEDURE `sitter_price`(
   in in_hours float,
   in age varchar(100),
   in no_of_sitters int,
   in no_of_days int
)
BEGIN
    SET @theSql=CONCAT('SELECT TRUNCATE(sum(price)*',in_hours,'*',no_of_days,'*',no_of_sitters,',2)');
    SET @theSql=CONCAT(@theSql,' as total_amount from job_prices jp join kids_ages ka on ka.id = jp.kids_age_id');
    SET @theSql=CONCAT(@theSql,' where ka.age in(',age,') and ' ,in_hours, ' between jp.start_hours and jp.end_hours ');      
    PREPARE stmt from @theSql; -- create a prepared stmt from the above concat
    EXECUTE stmt;   -- run it
    DEALLOCATE PREPARE stmt;    -- cleanup
END