1

HQL のストアド プロシージャを使用して現在のタイムスタンプを取得しようとしています。これは、私のコードが次のようになることを意味します。

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

これはうまくいきません。具体的にSystem.NullReferenceExceptionは、NHibernate HqlParser.cs ファイルの奥深くにスローします。私はこれを少しいじって、代わりに次のように動作させました:

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

必要なデータはありますが、HQL クエリはありません。元の形式のように、クエリで質問を表現したいと思います。

ここでの明白な質問は、「なぜ HQL を使用しているのですか?」です。session.CreateSQLQuery(...)MySQL 5.1 データベースに直接アクセスして、これを簡単に実行できることはわかっています。これは単に私の中心的な問題の例です。コードベース全体でパラメーターのないカスタム HQL 関数を使用していることが根本にあり、これらの HQL パラメーターのない関数をできるだけ分離して実行する統合テストが必要です。可能。

私のハックには、いくつかの重大な仮定が組み込まれています。たとえば、Contact テーブルにレコードがない場合、または Contact テーブルが存在しなくなった場合、結果は返されません。

4

1 に答える 1

1

データベース テーブルのコンテキスト外で CURRENT_TIMESTAMP() (またはその他のデータベース関数) を取得する方法は、データベースによって異なります。許可するものもあれば、許可しないものもあります。たとえば、Oracleはテーブルなしで選択を許可しないため、システムテーブルにDUALと呼ばれる単一の行を提供します。

NHibernate が HQL で主に実装しているのは、すべてのデータベース実装に共通の機能であるため、テーブルなしの選択を実装していないと思われます。

3 つのアプローチを提案できます。

  1. 「create view dtm as select current_timestamp() as datetime」など、テーブルなしの選択を非表示にするビューを作成します

  2. Oracle のアプローチに従い、select でテーブルとして使用できる単一行を含むユーティリティ テーブルを作成します。

  3. 「select current_timestamp()」のみを実行する単純なストアド プロシージャを作成します。

于 2012-09-19T13:37:48.263 に答える