JPQL / HQL group_concat SQLServer 2012与其他DBMS的兼容性

时间:2019-05-15 09:45:15

标签: java sql-server spring hibernate jpql

我使用休眠是为了使应用程序独立于任何DBMS,在应用程序的某些部分中,我需要使用group_concat,list_agg或string_agg来聚合相关表的ID。

我已经增强了休眠方言,以将hql函数(group_concat)与我正在使用的任何dbms上的任何等效项进行映射。将string_agg转换为postgresql,将list_agg转换为oracle。

问题变得存在,因为在SQL Server <2017中没有像group_concat这样的功能,并且需要在select中执行sql才能将结果投影为字段。

ListAGG in SQLSERVER

PostgreSQL

this.registerFunction("group_concat", new SQLFunctionTemplate(StandardBasicTypes.STRING, "STRING_AGG(?1 || '', ?2)"));

SQL Server

this.registerFunction("group_concat", new SQLFunctionTemplate(StandardBasicTypes.STRING, "STUFF( (?3 FOR XML PATH ('') ), 1, 1, '')"));

我的主要方法是在hql group_concat中允许一个新的第3个参数,以便在我以前用HQL编写并编译为SQL的SQL Server中接收直接执行的SQL。

protected String translateHqlToSql(String paramSql) {
        ASTQueryTranslatorFactory queryTranslatorFactory = new ASTQueryTranslatorFactory();
        SessionImplementor hibernateSession = this.em.unwrap(SessionImplementor.class);
        QueryTranslator queryTranslator = queryTranslatorFactory.createQueryTranslator("", paramSql, java.util.Collections.EMPTY_MAP, hibernateSession.getFactory(), null);
        Map<String,String> replacements = new HashMap<>();
        queryTranslator.compile(replacements, false);
        return queryTranslator.getSQLString();
    }

fallBackQuery = this.translateHqlToSql("SELECT a.id, "
                + "FROM Clients d "
                + "left join d.addresses a "
                + "WHERE d.id = c.id");


SELECT c.id, group_concat(a.id, ',', fallBackQuery)
FROM Clients c left join c.addresses a

我希望获得以下SQL

PostgreSQL

SELECT c.id, STRING_AGG(a.ID, ',')
FROM TB_CLIENT c
    LEFT JOIN TB_ADDRESS a ON a.FK_CLIENT = c.ID

SQLServer 2012

SELECT c.id,
    STUFF( 
        (SELECT a.ID 
        FROM TB_CLIENT d 
        LEFT JOIN TB_ADDRESS a ON a.FK_CLIENT = d.ID 
        WHERE d.ID = a.ID 
        FOR XML PATH),
    1, 1, '')
FROM TB_CLIENT c
LEFT JOIN TB_ADDRESS a ON a.FK_CLIENT = c.ID

问题开始于fallBackQuery,因为我需要编译另一个依赖的hql。

WHERE d.ID = a.ID 

可能我得到了一个完全错误的方法。

谢谢您的帮助,

0 个答案:

没有答案