基于每个查询定义排序规则

Posted

技术标签:

【中文标题】基于每个查询定义排序规则【英文标题】:Define collation on a per query basis 【发布时间】:2018-05-23 19:51:01 【问题描述】:

我们正在使用 Apache Cayenne 将现有的 MS SQL Server 数据库与我们的应用程序集成(我无权更改数据库 DDL,包括表/架构/数据库排序规则)。

数据库正在使用特定的排序规则(克罗地亚语),它定义了“nj”和“dž”等单个字符,所以当我执行LIKE 查询时:

select * from table where name like '%N%' 另一方面,如果我这样做,我得到的结果为零:select * from table where name like '%NJ%' 我得到多个结果。

显然,通过在查询末尾添加collate 可以轻松解决此问题,但我不知道使用 Cayenne 无法做到这一点。有什么方法可以在不放弃整个 ORM 优势的情况下实现这一点?

tl;dr:有没有办法在进入数据库之前对查询进行预处理,如下所示:

query = query + ' collate SQL_Latin1_General_CP1_CI_AS'

【问题讨论】:

【参考方案1】:

您可以尝试将自定义 DB 适配器与自定义 SQL 转换器一起使用,该转换器会将所需部分附加到所有选择查询。 对于 Cayenne 4.0 可以这样实现:

public class CustomSQLServerAdapter extends SQLServerAdapter 

    public CustomSQLServerAdapter(/* all params */) 
        super(/* all params */);
    

    @Override
    public SelectTranslator getSelectTranslator(SelectQuery<?> query, EntityResolver entityResolver) 
        return new SQLServerSelectTranslator(query, this, entityResolver) 
            @Override
            protected void doTranslate() 
                super.doTranslate();
                sql += " collate SQL_Latin1_General_CP1_CI_AS";
            
        ;
    

要使用此适配器,您可以为其贡献自定义检测器 (see docs) 或直接在 Modeler 中设置它(数据节点 -> 适配器)。

【讨论】:

以上是关于基于每个查询定义排序规则的主要内容,如果未能解决你的问题,请参考以下文章

如何实现基于连字符分隔的子串的多个自定义排序规则?

SQLite 自定义函数,聚合,排序规则

SQL Server转换数据库的排序规则

SQLSERVER的中文排序规则(转帖+亲自实践)

查询数据库中的排序顺序

土耳其语 SQL 排序规则的问题(土耳其语“I”)