【问题标题】:Sql query with optional fields for Search Web Application带有搜索 Web 应用程序可选字段的 Sql 查询
【发布时间】:2015-09-15 11:44:53
【问题描述】:

不是 SQL 专家:

我目前正在实现一个搜索网络应用程序。用户将向特定的Endpoint 发送GET request

Endpoint 将接受一组URL Params,并且请求可以带有可选字段。例如 1、2 或 3 个字段。

USER 的我的数据库表如下所示。

+--------------+---------+------+-----+---------+----------------+
| id        | firstName    | lastName | email | zip | phone      |
+--------------+---------+------+-----+---------+----------------+

现在,Web 应用程序将获得 GET RequestPhoneZipEmail

我有两种解决方案,但看起来都很糟糕:

Solution 1:
  1. 根据我收到的 URL 参数,有多个 SQL QueriesExecute

    Select * from User where phone=1111111111 and zip=12345 and email=test@email.com;

    Select * from User where phone=1111111111 and zip=12345;

    ... ...

等等............我最终会有很多查询,这将是一个糟糕的实现。也不好维护。

Solution 2:

我正在考虑的其他解决方案是有一个方法,它将根据我收到的 URL 参数构建 SQL 查询。

例子:

buildSQLQuery(phone,zip,email){

String sql = "Select * from User where "

if(phone!=null  && email!=null && zip!=null ){
sql = sql   + "phone = " + phone + " and zip = " + zip + " and email = " + email;
}else if (phone!=null  && email!=null && zip==null){
sql = sql + "phone = " + phone + " and email = " + email;
}
.......
......
And so on have all conditions and build that particular query.
}

我不喜欢这两种解决方案。

有没有办法编写一个单一的 SQL 查询来处理上述所有条件。

如果 URL 参数值是 NULL,那么这不会影响查询,我会得到预期的结果。

在我的情况下,未输入的可选值设置为NULL

我可以实现这样的东西吗?

Select * from User where (if notNull (phone))(phone = phone ) and (if notNull (email))(email = email ) and (if notNull (zip))(zip = zip )

如果上述任何一个值为空,则不要在where Condition 中使用该部分。

此外,我将始终存在一个字段,因此不会出现所有值都为空的情况。

我正在用 Java 和 Spring MVC 实现这个 Web 应用程序。如果有人可以指导我正确的方向。

谢谢。

【问题讨论】:

  • 是的,如果您在此处为您的桌子提供fiddle,您可以使用if() 执行此操作,这样很容易找到解决方案。
  • 您正在使用 Spring MVC。我强烈推荐你使用 Spring Data JPA 和 Hibernate 框架。 projects.spring.io/spring-data-jpa 这样你就不用写SQL样板代码了。
  • 你能给我一个使用spring-data-jpa的例子吗?就我而言。
  • 也见here

标签: java mysql sql spring spring-mvc


【解决方案1】:

我认为还有一种可能的解决方案,例如:

String sql = "Select * from User where 1=1 "

    if(phone!=null){
    sql +=  " and phone = " + phone ;}

    if(email!=null){
    sql +=  " and email = " + email ;}

    if(zip!=null){
    sql +=  " and zip = " + zip ;}

或者您可以尝试以下单个查询:

select * from User 
where (@phone is null OR phone = @phone) AND (@email is null OR email = @email) AND (@zip is null OR zip = @zip)

【讨论】:

  • 小心,这里很可能进行SQL注入。
  • 我很想知道这个答案是否可以以无法进行 SQL 注入的方式更新。
【解决方案2】:

你可以这样做:

SELECT * FROM User where(
   IF($phone != 0, IF(phone = $phone,1,0), 0) AND 
   IF($email != 0, IF(email = $email,1,0),0) AND 
   IF($zip != 0, IF(zip = $zip,1,0),0)
)

假设对于 PHP,您可以更改语法,可能这个查询不能完全完成这项工作,但如果您提供小提琴,我会修改它以给出正确的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    • 2019-11-10
    相关资源
    最近更新 更多