Использование ODP.Net с NHibernate с .net System.decimal - PullRequest
1 голос
/ 30 ноября 2010

Я использую ODP.net для запуска совокупного AVG для базы данных Oracle 10g.Я запускаю этот запрос непосредственно в базе данных, и он отлично работает:

выберите avg (ANSCHAFFUNGSKST) из IHObjekt

, он возвращает: 13.4493973163521

Ни интерфейсы HQL, ни интерфейсы CreateCriteria успешновыполнить запрос.Я получаю сообщение NHibernate «не удалось выполнить запрос».Однако я относительно уверен, что это ошибка ODP.Net, основанная на этой публикации .

. Существует решение для Oracle, просто TRUNC AVG.Тем не менее, команда TRUNC в Oracle отличается от SQL Server, и мне нужно / я хочу, чтобы мой код не зависел от базы данных.

Любые идеи о том, как можно уменьшить количество десятичных знаков, чтобы они соответствовали десятичному числуи самое главное, он работает на всех базах данных?

Source = NHibernate

StackTrace

  • NHibernate.Loader.Loader.DoList (сеанс ISessionImplementor, QueryParameters queryParameters)
  • NHibernate.Loader.Loader.ListIgnoreQueryCache (сессия ISessionImplementor, QueryParameters queryParameters)
  • NHibernate.Loader.Loader.List (сессия ISessionImplementor, QueryParameters1024 *
  • NHibernate.Hql.Ast.ANTLR.1028 *
  • NHibernate.Engine.Query.HQLQueryPlan.PerformList (QueryParameters queryParameters, сессия ISessionImplementor, результаты IList)
  • NHibernate.Impl.SessionImpl.List (строковый запрос, QueryParameters queryParameters, результаты IList)
  • NHibernate.Impl.istСтроковый запрос, параметры QueryParameters)
  • NHibernate.Impl.QueryImpl.List ()
  • DBTest_NHibernate.MainWindow.ButtonHQLQuery_Click (Отправитель объекта, RoutedEventArgs e) в C: \ ...

InnerException

[System.OverflowException] = {"Die arithmetische Operation hat einen Überlauf verursacht."} ... Арифметическая операция вызвала переполнение.

Source = Oracle.DataAccess

StackTrace

  • Oracle.DataAccess.Types.DecimalConv.GetDecimal (IntPtr numCtx)
  • Oracle.DataAccess.Client.OracleDataReader.GetDecimal (Int32 i)
  • Oracle.DataAccess.Client.OracleDataReader.GetValue (Int32 i)
  • Oracle.DataAccess.Client.OracleDataReader.get_Item (Int32 i)
  • NHibernate.Type.DoubleType.Get (IDataReader rs, индекс Int32)
  • NHibernate.Type.NullableType.NullSafeGet (IDataReader rs, имя строки)
  • NHibernate.Type.NulbleT.NullSafeGet (IDataReader rs, имена String [], сеанс ISessionImplementor, владелец объекта)
  • NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.GetResultColumnOrRow (строка объекта [], идентификатор объекта IResultTransforder для сеанса ISesultTransmer)
  • NHibernate.Loader.Loader..Loader.Loader.
  • NHibernate.Loader.Loader.DoList (сеанс ISessionImplementor, QueryParameters queryParameters)

Некоторые результаты тестирования HQL

  • выберите TRUNC (AVG (ANSCHAFFUNGSKST), 27) из IHObjekt - РАБОТАЕТ (ТОЛЬКО В ORACLE)
  • выберите TRUNC (AVG (ANSCHAFFUNGSKST), 28) из IHObjekt - НЕ РАБОТАЕТ
  • выберите AVG (ANSCHAFFUNGSKST) из IHObjekt - НЕ РАБОТАЕТ

NHibernate Генерируемый SQL

SELECT
    AVG(IHOBJEKT0_.ANSCHAFFUNGSKST) AS COL_0_0_,
    COUNT(IHOBJEKT0_.ANSCHAFFUNGSKST) AS COL_1_0_,
    MAX(IHOBJEKT0_.ANSCHAFFUNGSKST) AS COL_2_0_,
    MIN(IHOBJEKT0_.ANSCHAFFUNGSKST) AS COL_3_0_,
    SUM(IHOBJEKT0_.ANSCHAFFUNGSKST) AS COL_4_0_ 
FROM
    IHOBJEKT IHOBJEKT0_

Только AVG не работает в приведенном выше операторе SQL на Oracle с использованием ODP.Net. Используя SQL Server или клиент Oracle, он работает.

Ответы [ 2 ]

1 голос
/ 15 января 2013

Разбирая код, который мне дали, и разрезая его на более мелкие части, я могу подтвердить, что у вас возникнут проблемы при использовании двойных чисел с чрезмерным количеством цифр справа от запятой.

В отличие от OP, TRUNC (AVG (XXXX)) не работал в моем случае. Тем не менее:

TRUNC (двузначный, intvalue) и ROUND (двузначный, intvalue)

принес решение. Я проверил это с помощью nhibernate и простого OracleDataReader, используя odp.net

0 голосов
/ 08 декабря 2010

Проблема связана с тем, что возвращаемое значение не будет приведено к десятичному значению .Net из-за количества значений после десятичной точки.Кажется, что, хотя значение округляется до .Net, Oracle внутренне выдает исключение переполнения.

То, что я прочитал, Oracle подтвердило, что это сделано и не будет изменено.* Некоторые люди используют Trunc или катаются на строку, а затем удваивают, чтобы обойти проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...