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

发布于 2024-10-05 09:03:11 字数 3770 浏览 0 评论 0原文

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

select avg(ANSCHAFFUNGSKST) from IHObjekt

它返回: 13.4493973163521

无论 HQL 还是 CreateCriteria 接口都成功执行查询。我收到 NHibernate“无法执行查询”消息。但是,我相对确定这是基于此的 ODP.Net 错误 发布

Oracle 有一个解决方案,只需 TRUNC AVG 即可。然而,Oracle 与 SQL Server 中的 TRUNC 命令是不同的,我需要/想要让我的代码不特定于数据库。

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

源 = NHibernate

StackTrace

  • NHibernate.Loader.Loader.DoList(
  • ISessionImplementor 会话,QueryParameters queryParameters) NHibernate.Loader.Loader.ListIgnoreQueryCache(
  • ISessionImplementor 会话,QueryParameters queryParameters) NHibernate.Loader.Loader.List(ISessionImplementor 会话,QueryParameters queryParameters,ISet`1 querySpaces , IType[] resultTypes)
  • 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_NHibernate.MainWindow.ButtonHQLQuery_Click(Object sender, RoutedEventArgs e) in C:\...

InnerException

[System.OverflowException] = {"Die arithmetische Operation hat einen Überlauf verursacht."} ... 算术运算导致了溢出。

源 = 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.NullableType.NullSafeGet(IDataReader rs, String[]名称,ISessionImplementor 会话,对象所有者)
  • NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.GetResultColumnOrRow(Object[] row,IResultTransformer resultTransformer,IDataReader rs,ISessionImplementor 会话)
  • NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet,ISessionImplementor 会话, QueryParameters queryParameters、LockMode[] lockModeArray、EntityKey 可选ObjectKey、IList HydratedObjects、EntityKey[] 键、布尔 returnProxies)
  • NHibernate.Loader.Loader.DoQuery(ISessionImplementor 会话、QueryParameters queryParameters、布尔 returnProxies)
  • NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor 会话、 QueryParameters queryParameters, Boolean returnProxies)
  • NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)

一些 HQL 测试结果

  • select TRUNC(AVG(ANSCHAFFUNGSKST),27) from IHObjekt - WORKS (ONLY IN ORACLE)
  • select TRUNC(AVG(ANSCHAFFUNGSKST) ,28) from IHObjekt - DOES NOT WORK
  • 从 IHObjekt - DOES NOT WORK 选择 AVG(ANSCHAFFUNGSKST) -

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 在使用 ODP.Net 的 Oracle 上的上述 SQL 语句中不起作用。使用 SQL Server 或 Oracle 客户端就可以了。

I am using ODP.net to run the aggregate AVG against an Oracle 10g database. I run this query directly on the database and it works fine:

select avg(ANSCHAFFUNGSKST) from IHObjekt

it returns: 13.4493973163521

Niether the HQL nor the CreateCriteria interfaces successfully execute the query. I recieve an NHibernate 'could not execute query' message. However, I am relatively certain it is an ODP.Net error based on this posting.

There is a solution for Oracle, simply TRUNC the AVG. However, the TRUNC command is different in Oracle versus SQL Server and I need/want to keep my code from being database specific.

Any ideas about how I can reduce the number of decimal points so it fits within a decimal and most importantly, it works on all databases?

Source = NHibernate

StackTrace

  • 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()
  • DBTest_NHibernate.MainWindow.ButtonHQLQuery_Click(Object sender, RoutedEventArgs e) in C:\...

InnerException

[System.OverflowException] = {"Die arithmetische Operation hat einen Überlauf verursacht."} ... The arithmetic operation has caused an overflow.

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 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)

Some HQL Testing Results

  • select TRUNC(AVG(ANSCHAFFUNGSKST),27) from IHObjekt - WORKS (ONLY IN ORACLE)
  • select TRUNC(AVG(ANSCHAFFUNGSKST),28) from IHObjekt - DOES NOT WORK
  • select AVG(ANSCHAFFUNGSKST) from IHObjekt - DOES NOT WORK

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_

Only AVG does not work in the above SQL statement on Oracle using ODP.Net. Using SQL Server or the Oracle client it works.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

智商已欠费 2024-10-12 09:03:12

通过剖析我得到的代码并将其切成更小的部分,我可以确认,当使用逗号右侧数字过多的双精度数时,您会遇到问题。

与 OP 相比,TRUNC(AVG(XXXX)) 在我的情况下不起作用。然而:

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

带来了解决方案。我使用 odp.net 使用 nhibernate 和简单的 OracleDataReader 对此进行了测试

By dissecting the code I was given and cutting it into smaller pieces I can confirm, that you will run into problems when using doubles with excessive amounts of digits right of the comma.

In contrast to the OP, TRUNC(AVG(XXXX)) did not work in my case. However:

TRUNC(doubledigit, intvalue) and ROUND(doubledigit, intvalue)

brought a solution. I tested this with nhibernate and a simple OracleDataReader using odp.net

携余温的黄昏 2024-10-12 09:03:12

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

根据我所读到的内容,Oracle 已经确认这是设计使然,不会改变。

有些人使用 Trunc 或 cating 到一个字符串然后再使用一个 double 来解决这个问题。

The issue is due to the value being returned will not cast to a .Net Decimal due to the number of values after the decimal point. It seems that even though the value is rounded by .Net, Oracle internally throw an overflow exception.

Frm what I have read Oracle have confirmed this is by design and won't be changed.

Some people are using Trunc or catsing to a string then a double to get round the issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文