如何在HQL中调用没有表名的存储过程?

时间:2012-09-18 20:20:47

标签: database nhibernate datetime hql

我正在尝试通过HQL中的存储过程获取当前时间戳。这意味着我的代码如下所示:

var currentTimestamp =
    session.CreateQuery("SELECT CURRENT_TIMESTAMP()")
           .UniqueResult<DateTime>();

这不起作用。具体来说,它会在NHibernate HqlParser.cs文件中抛出System.NullReferenceException深。我玩了一下这个,并得到了以下工作:

var currentTimestamp =
    session.CreateQuery("SELECT CURRENT_TIMESTAMP() FROM Contact")
           .SetMaxResults(1)
           .UniqueResult<DateTime>();

现在我有我想要的数据,但我没有HQL查询。我希望查询代表我问的问题 - 就像我的原始格式一样。

这里一个显而易见的问题是“你为什么使用HQL?”我知道我可以轻松地使用这个session.CreateSQLQuery(...),直接命中我们的MySQL 5.1数据库。这只是我的核心问题的一个例子,根源是我在整个代码库中使用自定义无参数的HQL函数,并且我想要进行集成测试,以便在尽可能多的隔离中运行这些HQL无参数函数可能的。

我的hack也有一些严肃的假设。它不会返回结果,例如,如果Contact表中没有记录,或者Contact表不再存在。

1 个答案:

答案 0 :(得分:1)

在数据库表的上下文之外检索CURRENT_TIMESTAMP()(或任何其他数据库函数)的方法因数据库而异 - 有些允许,有些则不允许。例如,Oracle不允许没有表的select,因此它们为系统表提供了一行称为DUAL的行。

我怀疑NHibernate在HQL中实现的主要功能是在所有数据库实现中都很常见,因此没有实现无表选择。

我可以提出三种方法:

  1. 创建一个隐藏无表格选择的视图,例如'create view dtm as select current_timestamp()as datetime'

  2. 遵循Oracle方法并创建一个实用程序表,其中包含一行,您可以将其用作选择

  3. 中的表
  4. 创建一个只执行'select current_timestamp()'的简单存储过程