如何将任何给定的SQL / HQL选择查询动态转换为等效计数查询?

时间:2018-06-19 11:40:08

标签: c# sql oracle nhibernate hql

我想将任何给定的选择查询转换为等效计数查询。选择查询可以是有效的SQL或HQL查询。以下是我的尝试。

    /// <summary>
    /// Converts select query into equivalent count query
    /// </summary>
    protected string ConvertToCountQuery(string selectQuery)
    {
        if (string.IsNullOrWhiteSpace(selectQuery))
        {
            return string.Empty;
        }

        string[] selectParts = selectQuery.ToLower().Split(new string[] { "select" }, StringSplitOptions.RemoveEmptyEntries);
        string[] fromParts = selectParts[0].Split(new string[] { "from" }, StringSplitOptions.RemoveEmptyEntries);
        selectParts[0] = string.Format("select count(*) from{0}", fromParts[1]);
        return string.Concat(selectParts);
    }

它对SQL查询工作很好,因为它们不区分大小写,但是对于HQL查询,它不区分大小写。我该如何保存案件,同时仍然要获得等价计数查询。

用于SQL的示例测试数据:

select u.username, u.email, u.first_name, u.last_name from users u where u.username like '% %';

SQL的预期输出:

select count(*) from users u where u.username like '% %';

HQL的样本测试数据:

select u.Username, u.Email, u.FirstName, u.LastName from User u where u.Username like '% %';

HQL的预期输出:

select count(*) from Users u where u.Username like '% %';

请注意HQL查询中的区分大小写。

2 个答案:

答案 0 :(得分:0)

好的,我自己找到了解决方案。

    /// <summary>
    /// Converts select query into equivalent count query
    /// </summary>
    public static string ConvertToCountQuery(string selectQuery)
{
    if (string.IsNullOrWhiteSpace(selectQuery) || !selectQuery.ToLower().Contains("select"))
    {
        return string.Empty;
    }

    return string.Concat(
            "select count(*)",
            selectQuery.Substring(selectQuery.ToLower().IndexOf(" from")));
}

答案 1 :(得分:0)

我会尝试将给定查询放入子查询中

var countQuery = string.Format("select count(*) from ({0})", selectQuery);

它将变成这种查询:

select count(*) from (select ... from User u where u.Username like '% %');

我不知道它是否有效。 Oracle需要支持此功能(FROM子句中的子查询)。 HQL也需要支持它(在很多方面它通常是相当透明的,因此有希望)。如果没有,我会认为通过合理的努力和可接受的可靠性是不可能的。

考虑对这些类型的任务使用linq或query over,因为这些API在运行时可靠地构建查询时更加灵活。 AFAIK都内置了计数支持。