如何将任何给定的 SQL/HQL 选择查询动态转换为等效计数查询?
Posted
技术标签:
【中文标题】如何将任何给定的 SQL/HQL 选择查询动态转换为等效计数查询?【英文标题】:How to dynamically convert any given SQL/HQL select query to equivalent count query? 【发布时间】:2018-11-28 08:47:11 【问题描述】:我想将任何给定的选择查询转换为等效的计数查询。选择查询可以是有效的 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(*) from0", 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 查询中区分大小写。
【问题讨论】:
【参考方案1】:好的,我自己找到了解决方案。
/// <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")));
【讨论】:
查询有group by子句时不起作用。当它在 select 子句中包含子查询时(使用另一个 from 子句,但不是您要查找的 from 子句),它也不起作用。 @StefanSteinegger 我明白你所说的分组是什么意思,你能解释一下'select 子句(带有另一个 from 子句..')是什么意思吗?你能给出一个测试查询吗?跨度> 在参考文档中(搜索子查询):select cat.id, (select max(kit.weight) from cat.kitten kit) from Cat as cat
【参考方案2】:
我会尝试将给定的查询放入子查询中:
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,两者都内置了计数支持。
【讨论】:
以上是关于如何将任何给定的 SQL/HQL 选择查询动态转换为等效计数查询?的主要内容,如果未能解决你的问题,请参考以下文章