MySQL准备的语句在条件不起作用的情况下

时间:2017-09-11 05:27:03

标签: mysql stored-procedures prepared-statement

这是实际查询

select taken_date, DATE_FORMAT(taken_date, '%Y') taken_date_year, count(id) num_of_orders, sum(total_order_days) total_work_days from
(   
    select id, taken_date, getNumOfWorkDaysForOrder(order.order_num) total_order_days from order 
    where order.is_active = 1 and order.deleted_at is null and order.vendor_id = vendor_input  and 
        order.company_id = company_input and order.contact_id = contact_input and order.candidate_id = candidate_input
    order by taken_date 
) as order_years group by YEAR(taken_date) order by taken_date desc;

我想基于输入添加where条件,如果它不是null,尝试准备语句和连接以将where条件添加到查询但没有运气。

DELIMITER $$
CREATE PROCEDURE 
  getAllActiveOrdersGroupByTakenDate(vendor_input INT, company_input INT, contact_input INT, candidate_input INT)
BEGIN
    SET @prepareQuery = "select id, taken_date, getNumOfWorkDaysForOrder(order.order_num) total_order_days from order 
        where order.vendor_id = "+ vendor_input +" and order.is_active = 1 and order.deleted_at is null";

    IF company_input IS NOT NULL THEN
        SET @prepareQuery = CONCAT(@prepareQuery, ' ', "and order.company_id = "+company_input);
    END IF;
    IF contact_input IS NOT NULL THEN
        SET @prepareQuery = CONCAT(@prepareQuery, ' ', "and order.contact_id = "+contact_input);
    END IF;
    IF candidate_input IS NOT NULL THEN
        SET @prepareQuery = CONCAT(@prepareQuery, ' ', "and order.candidate_id = "+candidate_input);
    END IF;

    SET @finalQueryPart1 = CONCAT("select taken_date, DATE_FORMAT(taken_date, '%Y') taken_date_year, count(id) num_of_orders, sum(total_order_days) total_work_days from
    (", @prepareQuery);

    SET @finalQuery = CONCAT(@finalQueryPart1, ") as order_years group by YEAR(taken_date) order by taken_date desc");

    PREPARE stmt FROM @finalQuery;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

END $$
DELIMITER ;

有人可以帮助我实现这个目标吗?

1 个答案:

答案 0 :(得分:1)

更新:在编辑问题之前,您的CONCAT()语法存在问题。

如果要附加内容,则必须将其分配回原始字符串。 CONCAT()是一个返回连接字符串的函数。它没有任何修改你用作参数的变量的副作用。

WRONG:

CONCAT(@prepareQuery, ' ', "and order.company_id=company_input");

RIGHT:

SET @prepareQuery = CONCAT(@prepareQuery, ' ', "and order.company_id=company_input");

另外,我不确定你是否可以在这些表达式中引用过程输入参数。

坦率地说,我几乎不使用存储过程。 MySQL的存储过程实现很糟糕。它效率低,不能保存编译过程,没有调试器,没有软件包等等。

主要是我只是从我的应用程序执行动态SQL。您可以使用熟悉的语言进行调试,代码重用,熟悉的字符串操作。

据我所知,存储过程是Oracle和Microsoft SQL Server社区的传统,但避免MySQL中的存储过程确实更好。