JPQL / HQL group_concat Совместимость SQLServer 2012 с другими СУБД - PullRequest
0 голосов
/ 15 мая 2019

Я использую hibernate, чтобы сделать приложение независимым от любой СУБД. В некоторых частях приложения мне нужно объединить идентификаторы связанной таблицы с group_concat, list_agg или string_agg.

Я улучшил спящие диалекты, чтобы отобразить функцию hql (group_concat) с любым из эквивалентов на любых используемых мной дБмах. string_agg в postgresql, list_agg в oracle.

Проблема возникает из-за того, что в SQL Server <2017 нет такой функции, как group_concat, и требуется выполнить sql в select для проецирования результата в виде поля. </p>

ListAGG в 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, '')"));

Мой основной подход состоял в том, чтобы разрешить новый 3-й параметр в hql group_concat для получения прямого sql для выполнения в случае SQL Server, который я ранее писал на HQL, и компиляции в 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 

Возможно, у меня совершенно неправильный подход.

Спасибо, любая помощь приветствуется

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...