尝试搜索部分匹配的属性

Trying to Search for partial matching attributes

所以我正在尝试查询(Java) 数据库(h2) 以获得搜索功能。要搜索查询,应该找到属性部分匹配的条目。

搜索可以针对属性的每个组合,因此检查它们是否有效。

public List<Horse> search(Horse mockHorse) {
    LOGGER.trace("Search horses which match{}", mockHorse);
    String query = "SELECT * FROM " + TABLE_NAME + " WHERE" +
        "(UPPER(name) LIKE UPPER(%?%)) AND "+
        "UPPER(description) LIKE UPPER(%?%)"+
        " AND breed LIKE ? AND ranking=?";
    // set value to wildcard to match every value
    if (!mockHorse.getBreed().equals("")) {
        mockHorse.setBreed("%");
    }

(sorry for that format it didnt take it otherwise)

    Object[] obj = new Object[]{
        mockHorse.getName(),
        mockHorse.getDescription(),
        mockHorse.getBreed(),
        mockHorse.getRanking()
    };

    if (!(mockHorse.getBirthdate()==null)){
        query+= " AND birthdate <=?";
        obj = new Object[] {
            mockHorse.getName(),
            mockHorse.getDescription(),
            mockHorse.getBreed(),
            mockHorse.getRanking(),
            mockHorse.getBirthdate().toString()
        };
    }

    final String sql = query +';';
    return jdbcTemplate.query(sql,obj, this::mapRow);
}

然而,无论我尝试修复它,我只会得到新的错误,目前我被困在

Syntax error in SQL statement "SELECT * FROM HORSE WHERE(UPPER(NAME) LIKE UPPER(%[*]?%)) AND UPPER(DESCRIPTION) LIKE UPPER(%?%) AND BREED LIKE ? AND RANKING=? AND BIRTHDATE <=?;"; expected "), NOT, EXISTS, INTERSECTS, UNIQUE"; SQL
statement:
SELECT * FROM Horse WHERE(UPPER(name) LIKE UPPER(%?%)) AND UPPER(description) LIKE UPPER(%?%) AND breed LIKE ? AND ranking=? AND birthdate <=?; [42001-200]

你能给我一个提示,告诉我我做错了什么吗? (我尝试从 UPPER 中删除 ' 并将它们移出 UPPER ('UPPER') 并将其包裹在 % (UPPER('%?%')).

周围

问题出在你的 where 条件上。

WHERE
    (UPPER(NAME) LIKE UPPER(%[*]?%)) 
    AND UPPER(DESCRIPTION) LIKE UPPER(%?%) 
    AND BREED LIKE ? 
    AND RANKING = ? 
    AND BIRTHDATE <=?

前两个条件无效SQL。如果你想在查询中将参数连接为搜索字符串,你应该:

WHERE
    UPPER(NAME) LIKE CONCAT('%[*]', UPPER(?), '%') 
    AND UPPER(DESCRIPTION) LIKE CONCAT('%', UPPER(?), '%') 
    AND BREED LIKE CONCAT('%', ?, '%')
    AND RANKING = ? 
    AND BIRTHDATE <=?

注意:由于 BREED 上的过滤器使用 LIKE,我假设您在这里也需要通配符。

另一种方法是在您的应用程序中生成串联字符串。这在应用程序方面应该不费吹灰之力,并设置更清晰的 SQL 代码:

WHERE
    UPPER(NAME) LIKE ?
    AND UPPER(DESCRIPTION) LIKE ?
    AND BREED LIKE ?
    AND RANKING = ? 
    AND BIRTHDATE <=?
  1. 您需要使用 '%' || ? || '%' 而不是 %?%

  2. UPPER函数可以模拟不区分大小写的LIKE,但是这种模拟不能正确处理一些国家的字母,并不是每个字母都有1:1 小写和大写变体之间的映射。使用 ILIKE 更好更简单:

name ILIKE '%' || ? || '%'
  1. 如果你的参数可以包含_%,你需要用一些字符转义它们并在LIKE / ILIKE中添加ESCAPE子句:
name ILIKE '%' || REGEXP_REPLACE(?, '([_%\])', '\') || '%' ESCAPE '\'

在 Java 代码中,您需要键入 \ 以获得字符串中的 \\\ 代表 \)。如果您的参数中未使用 _%,则不需要此额外转换。

您的 SQL 有两个地方需要修复。