我正在使用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来解决问题。