【问题标题】:Dynamic MySQL Where Clause in Stored Procedure存储过程中的动态 MySQL Where 子句
【发布时间】:2013-02-05 15:55:38
【问题描述】:

我有一个问题,也许它很简单(对你们大师而言)。

我正在将我的 SQL 分页类从 C# 转换为 MySQL 存储过程。在我的 C# 自制对象中,查询是根据条件动态构建的。示例:

if(keywords is not null)
{ 
  whereClause += "WHERE description LIKE '%keywords%'"
}
if(price is not null)
{
  whereClause += "AND price = '%price%'"
}

....

string query = "SELECT col1, col2 FROM tblThreads " + whereClause

现在,我的问题是:如何在 MySQL 中执行与此类似的动态 where 子句?或者更确切地说,如果他们没有为这些参数输入任何内容,我将如何告诉存储过程中的 MySQL 跳过这些?即:

SELECT col1, col2 FROM tblThreads

如果这些参数为空,类似的方法会起作用吗?

SELECT col1, col2 FROM tblThreads WHERE (IS NULL @keywords OR description like '%@keywords%'

??

谢谢大家。

【问题讨论】:

    标签: mysql sql procedure


    【解决方案1】:
    DELIMITER $$
    CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_Name4`(
     IN a int(255),
     IN b int(255),
     IN dept_id_in int(255)
    )
    BEGIN
         SELECT
            emp.emp_id, emp.emp_name,
            emp.emp_job, 
            emp.dept, 
            emp.percent_doctor,
            emp.percent_center,
            patient_exam.exam_id,
            patient_exam.p_id,
            ABS(SUM(patient_exam.exam_price)) as SUM_price,
            ABS((SUM(patient_exam.exam_price)*  emp.percent_center )/100   ) as total_doc,
            ABS((SUM(patient_exam.exam_price)*  emp.percent_doctor )/100   ) as total_center
          FROM emp
          left join patient_exam 
          ON emp.emp_id = patient_exam.doctor
          WHERE emp.emp_is_delete=0 and patient_exam.ex_is_delete=0 and 1=1 
    
    CASE WHEN dept_id_in IS not NULL 
                            THEN
                            and patient_exam.dept_id=dept_id_in
    
                            END   
    
                            group by emp.emp_id, patient_exam.exam_id order by emp.emp_id, patient_exam.exam_id desc limit a,b;
    
            END$$
    DELIMITER ;
    

    【讨论】:

      【解决方案2】:
      SELECT col1, col2 
      FROM tblThreads 
      WHERE case when @keywords is not null then description like '%' + @keywords + '%' when @price is not null then price like'%' + @price + '%' end 
      

      【讨论】:

        【解决方案3】:

        您可以使用CASE 语句来检查@keywords 的值,例如。

        SELECT  col1, col2 
        FROM    tblThreads 
        WHERE   description LIKE  CASE WHEN @keywords IS NULL 
                                    THEN description
                                    ELSE CONCAT('%', @keywords, '%')
                                    END
                AND
                price LIKE  CASE WHEN @price IS NULL 
                                    THEN price
                                    ELSE CONCAT('%', @price, '%')
                                    END
        

        【讨论】:

        • 如果所有参数都为空怎么办?这不会导致执行不力吗? IE: description LIKE '%%' AND price LIKE '%%' AND param3 LIKE '%%' AND ... paramX LIKE '%%'?
        • 忽略我最后的评论。如果我使用 1 = 1 方法,然后在后面插入一个带有 CASE WHEN @price <> NULL THEN AND price LIKE '%price%' 的 case 语句,我猜应该可行……我从未尝试过,所以这是推测。
        【解决方案4】:

        如果您允许他们查询整个数据库,最简单的方法是在您的语句中添加 1 = 1 类似

        whereClause = "WHERE 1 = 1"
        
        if(keywords is not null)
        { 
         whereClause += "AND description LIKE '%keywords%'"
        }
        if(price is not null)
        {
         whereClause += "AND price = '%price%'"
        }
        

        【讨论】:

        • 我喜欢这个。我自己使用它,因为当我必须对 SQL 语句进行“大量”解析时,即以编程方式删除 AND 子句。允许您“返回上一个“AND”,并删除该行等。折扣 WHERE 子句使这更容易。
        • 我以前看过一次,尽管它没有回答我原来的问题,但它很有趣。假设我坚持我的 C# 对象类,现在我正在尝试确定我是否使用“AND”(我有一个布尔变量,在我使用 AND 的那一刻设置为 true。)假设我这样做,我会不必跟踪我何时使用我的第一个参数,对吗?这是否有任何性能损失,并且 1 = 1 是否会导致任何问题?
        • 刚刚在这里查看了一些额外的细节:stackoverflow.com/questions/8149142/where-1-1-statement我真的很喜欢这个想法,并将尝试实现它。谢谢你的提示!如果我决定采用这种方法,我也可以最终使用这种方法构建我的存储过程。谢谢大家。
        猜你喜欢
        • 2011-02-08
        • 2012-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多