如何将任何给定的 SQL/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 查询中的区分大小写。

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

/// <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")));
}

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

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,两者都有内置的计数支持。

最新更新