使用带有.net System.decimal的NHibernate的ODP.Net

时间:2010-11-30 16:22:05

标签: nhibernate decimal odp.net average

我正在使用ODP.net对Oracle 10g数据库运行聚合AVG。我直接在数据库上运行此查询,它工作正常:

从IHObjekt选择avg(ANSCHAFFUNGSKST)

它返回:13.4493973163521

NME HQL和CreateCriteria接口都无法成功执行查询。我收到一个NHibernate'无法执行查询'消息。但是,我相对肯定这是基于此posting的ODP.Net错误。

Oracle有一个解决方案,只需TRUNC AVG即可。但是,TRUNC命令在Oracle与SQL Server中是不同的,我需要/希望保持我的代码不受数据库特定的影响。

关于如何减少小数点数以使其符合小数点的任何想法,最重要的是,它适用于所有数据库?

Source = NHibernate

栈跟踪

  • NHibernate.Loader.Loader.DoList(ISessionImplementor session,QueryParameters queryParameters)
  • NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session,QueryParameters queryParameters)
  • NHibernate.Loader.Loader.List(ISessionImplementor session,QueryParameters queryParameters,ISet`1 querySpaces,IType [] resultTypes)
  • NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.List(ISessionImplementor session,QueryParameters queryParameters)
  • NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session,QueryParameters queryParameters)
  • NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters,ISessionImplementor session,IList results)
  • NHibernate.Impl.SessionImpl.List(String query,QueryParameters queryParameters,IList results)
  • NHibernate.Impl.SessionImpl.List(String query,QueryParameters parameters)
  • NHibernate.Impl.QueryImpl.List()
  • C:\ ...
  • 中的DBTest_NHibernate.MainWindow.ButtonHQLQuery_Click(Object sender,RoutedEventArgs e)

的InnerException

[System.OverflowException] = {“Die arithmetische Operation hateinenÜberlaufverursacht。”} ...算术运算导致溢出。

Source = Oracle.DataAccess

栈跟踪

  • 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 index)
  • NHibernate.Type.NullableType.NullSafeGet(IDataReader rs,String name)
  • NHibernate.Type.NullableType.NullSafeGet(IDataReader rs,String [] names,ISessionImplementor session,Object owner)
  • NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.GetResultColumnOrRow(Object [] row,IResultTransformer resultTransformer,IDataReader rs,ISessionImplementor session)
  • NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet,ISessionImplementor session,QueryParameters queryParameters,LockMode [] lockModeArray,EntityKey optionalObjectKey,IList hydratedObjects,EntityKey [] keys,Boolean returnProxies)
  • NHibernate.Loader.Loader.DoQuery(ISessionImplementor session,QueryParameters queryParameters,Boolean returnProxies)
  • NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session,QueryParameters queryParameters,Boolean returnProxies)
  • NHibernate.Loader.Loader.DoList(ISessionImplementor session,QueryParameters queryParameters)

一些HQL测试结果

  • 从IHObjekt选择TRUNC(AVG(ANSCHAFFUNGSKST),27) - 作品(仅限于ORACLE)
  • 从IHObjekt选择TRUNC(AVG(ANSCHAFFUNGSKST),28) - 不工作
  • 从IHObjekt选择AVG(ANSCHAFFUNGSKST) - 不工作

NHibernate Generated 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_

使用ODP.Net,只有AVG在Oracle上面的SQL语句中不起作用。使用SQL Server或Oracle客户端,它可以工作。

2 个答案:

答案 0 :(得分:1)

通过剖析我给出的代码并将其剪切成更小的部分,我可以确认,当使用逗号的数字位数过多的双打时,你会遇到问题。

与OP相反,TRUNC(AVG(XXXX))在我的情况下不起作用。但是:

  

TRUNC(doubledigit,intvalue)和ROUND(doubledigit,intvalue)

带来了解决方案。我用nhibernate和一个简单的OracleDataReader使用odp.net

测试了这个

答案 1 :(得分:0)

问题是由于小数点后面的值的数量,返回的值不会转换为.Net Decimal。似乎即使该值被.Net四舍五入,Oracle内部也会抛出溢出异常。

Frm我所读到的Oracle已经证实这是设计上的,不会改变。

有些人正在使用Trunc或catsing一个字符串然后使用double来解决问题。