将ODP.Net与NHibernate和.Net System.decimal一起使用

将ODP.Net与NHibernate和.Net System.decimal一起使用,nhibernate,decimal,odp.net,average,Nhibernate,Decimal,Odp.net,Average,我正在使用ODP.net对Oracle 10g数据库运行聚合平均值。我直接在数据库上运行此查询,效果很好: 从IHObjekt中选择平均值(Anshaffungskt) 它返回:13.4493973163521 但是HQL和CreateCriteria接口都成功地执行了查询。我收到一条NHibernate“无法执行查询”消息。然而,基于此,我相对确定这是一个ODP.Net错误 有一个针对Oracle的解决方案,就是TRUNC AVG。但是,TRUNC命令在Oracle和SQL Server中是不

我正在使用ODP.net对Oracle 10g数据库运行聚合平均值。我直接在数据库上运行此查询,效果很好:

从IHObjekt中选择平均值(Anshaffungskt)

它返回:13.4493973163521

但是HQL和CreateCriteria接口都成功地执行了查询。我收到一条NHibernate“无法执行查询”消息。然而,基于此,我相对确定这是一个ODP.Net错误

有一个针对Oracle的解决方案,就是TRUNC AVG。但是,TRUNC命令在Oracle和SQL Server中是不同的,我需要/希望我的代码不特定于数据库

关于如何减少小数点的数量,使其适合一个小数点,最重要的是,它适用于所有数据库,有什么想法吗

来源=NHibernate 堆栈跟踪
  • NHibernate.Loader.Loader.DoList(ISessionImplementor会话,QueryParameters QueryParameters)
  • NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor会话,QueryParameters QueryParameters)
  • NHibernate.Loader.Loader.List(ISessionImplementor会话,QueryParameters QueryParameters,ISet`1查询空间,IType[]结果类型)
  • NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.List(ISessionImplementor会话,QueryParameters QueryParameters)
  • NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor会话,QueryParameters QueryParameters)
  • NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters QueryParameters,ISessionImplementor会话,IList结果)
  • NHibernate.Impl.SessionImpl.List(字符串查询、QueryParameters QueryParameters、IList结果)
  • NHibernate.Impl.SessionImpl.List(字符串查询、QueryParameters参数)
  • NHibernate.Impl.QueryImpl.List()
  • DBTest\u NHibernate.main window.ButtonHQLQuery\u在C:\
内部异常 [System.OverflowException]={“Die arithmetische Operation hat einenÜberlauf verursacht.”。。。算术运算导致溢出

Source=Oracle.DataAccess 堆栈跟踪
  • Oracle.DataAccess.Types.DecimalConv.GetDecimal(IntPtr numCtx)
  • Oracle.DataAccess.Client.OracleDataReader.GetDecimal(int32i)
  • Oracle.DataAccess.Client.OracleDataReader.GetValue(Int32 i)
  • Oracle.DataAccess.Client.OracleDataReader.get_项(Int32 i)
  • NHibernate.Type.DoubleType.Get(IDataReader rs,Int32索引)
  • NHibernate.Type.NullableType.NullSafeGet(IDataReader rs,字符串名)
  • NHibernate.Type.NullableType.NullSafeGet(IDataReader rs,字符串[]名称,ISessionImplementor会话,对象所有者)
  • NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.GetResultColumnRow(对象[]行,IResultTransformer resultTransformer,IDataReader rs,ISessionImplementor会话)
  • NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet、ISessionImplementor会话、QueryParameters QueryParameters、LockMode[]lockModeArray、EntityKey optionalObjectKey、IList HydreatedObject、EntityKey[]键、布尔返回代理)
  • NHibernate.Loader.Loader.DoQuery(ISessionImplementor会话、QueryParameters QueryParameters、布尔返回代理)
  • NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor会话、QueryParameters QueryParameters、Boolean returnProxies)
  • NHibernate.Loader.Loader.DoList(ISessionImplementor会话,QueryParameters QueryParameters)
一些HQL测试结果
  • 从IHObjekt-WORKS(仅在ORACLE中)中选择TRUNC(平均值(Anschaffengskst),27)
  • 从IHObjekt中选择TRUNC(平均值(Anschaffengskst),28)-不工作
  • 从IHObjekt中选择平均值(Anshaffungskt)-不工作
NHibernate生成的SQL
在使用ODP.Net的Oracle上,上述SQL语句中只有AVG不起作用。使用SQL Server或Oracle客户端,它可以正常工作。

问题是由于返回的值不会转换为.Net十进制,因为小数点后的值数量太多。看起来,即使该值被.Net舍入,Oracle内部也会抛出溢出异常

Frm我所读到的甲骨文已经证实这是设计的,不会改变


有些人使用Trunc或catsing转换为字符串,然后使用double来解决这个问题。

问题是因为返回的值不会转换为.Net十进制,因为小数点后的值的数量太多。看起来,即使该值被.Net舍入,Oracle内部也会抛出溢出异常

Frm我所读到的甲骨文已经证实这是设计的,不会改变


有些人使用Trunc或catsing转换为字符串,然后转换为double来回避这个问题。

通过剖析我收到的代码并将其切割成更小的片段,我可以确认,当使用逗号右侧数字过多的double时,您将遇到问题

与OP不同的是,TRUNC(AVG(XXXX))在我的案例中不起作用。然而:

TRUNC(双位数,intvalue)和ROUND(双位数,intvalue)


带来了一个解决方案。我使用nhibernate和一个简单的OracleDataReader使用odp.net测试了这一点,通过剖析我得到的代码并将其切成更小的部分,我可以确认,当使用逗号右边数字过多的双精度时,您将遇到问题

与OP不同的是,TRUNC(AVG(XXXX))在我的案例中不起作用。然而:

TRUNC(双位数,intvalue)和ROUND(双位数,intvalue)


带来了一个解决方案。我使用nhibernate和一个简单的OracleDataReader使用odp.net测试了这一点。发布包含stacktrace的完整异常。您可以发布由nhiberate生成的查询吗?发布包含stacktrace的完整异常。您可以发布由nhiberate生成的查询吗?感谢您的输入,然而,我的目标是防止系统发生故障
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_