简体   繁体   English

ODP.NET:Oracle.ManagedDataAccess.Client.OracleException (0x80004005):.NET 5(核心)应用程序上的 ORA-01841

[英]ODP.NET: Oracle.ManagedDataAccess.Client.OracleException (0x80004005): ORA-01841 on .NET 5 (Core) application

trying to execute a select with Oracle.ManagedDataAcces.Client (ODP.NET) with a C# .NET 5 web app. trying to execute a select with Oracle.ManagedDataAcces.Client (ODP.NET) with a C# .NET 5 web app.

Oracle.ManagedDataAcces.Client version is latest 3.21.1 as of 02/06/2021.截至 2021 年 2 月 6 日,Oracle.ManagedDataAcces.Client 版本是最新的 3.21.1。

The error:错误:

Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware 1 An unhandled exception has occurred while executing the request. Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware 1执行请求时发生未处理的异常。 Oracle.ManagedDataAccess.Client.OracleException (0x80004005): ORA-01841: (full) year must be between -4713 and +9999 , and not be 0 at OracleInternal.ServiceObjects.OracleConnectionImpl.VerifyExecution(Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, SqlStatementType sqlStatementType, Int32 arrayBindCount, OracleException& exceptionForArrayBindDML, Boolean& hasMoreRowsInDB, Boolean bFirstIterationDone) Oracle.ManagedDataAccess.Client.OracleException (0x80004005): ORA-01841: (full) year must be between -4713 and +9999 , and not be 0 at OracleInternal.ServiceObjects.OracleConnectionImpl.VerifyExecution(Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, SqlStatementType sqlStatementType, Int32 arrayBindCount, OracleException& exceptionForArrayBindDML, Boolean& hasMoreRowsInDB, Boolean bFirstIterationDone)

This is the query code这是查询代码

   public async Task<int> GetMyCount(string userName, int THE_YEAR)
    {
        try
        {
            string TEST = "STACK_OVERFLOW_TEST";
            builder.Clear();

            builder.Append($@" SELECT COUNT(*) 
                FROM {configuration.SCHEMA}.SOME_TABLE CA 
                INNER JOIN {configuration.SCHEMA}.SOME_OTHER_TABLE CS 
                ON CS.ID=CA.ID ");

            if (viewNotAll)
            {
                builder.Append($" INNER JOIN {unitOfWork.oracleDbOptions.DBSchemaQP}.ANOTHER_TABLE UT ON CA.SOME_FIELD = UT.SOME_FIELD ");
            }

            builder.Append(@$" WHERE CA.DATE_TO_FILET BETWEEN TO_DATE(CONCAT('0101', :THE_YEAR),'DDMMYYYY') 
            AND TO_DATE(CONCAT('3112', :THE_YEAR),'DDMMYYYY') ");


            if (TEST == "NO")
                builder.Append(" AND CS.TEST_FIELD=0 ");
            else
                builder.Append(" AND CS.TEST_FIELD=:THE_TEST_FIELD ");


            int result = 0;

            using (var cmd = unitOfWork.connection.CreateCommand())
            {

                cmd.Parameters.Add("THE_YEAR", OracleDbType.Int16, 4, THE_YEAR, ParameterDirection.Input);
                cmd.Parameters.Add("THE_TEST_FIELD", OracleDbType.Varchar2, 20, userName, ParameterDirection.Input);

                cmd.CommandText = builder.ToString();
                using (var reader = await cmd.ExecuteReaderAsync())
                {
                    while (await reader.ReadAsync())
                    {
                        result = reader.IsDBNull(0) ? 0 : reader.GetInt32(0);
                    }
                }

                return result;
            }
        }
        catch (Exception)
        {
            throw;
        }
    }

Executing the query in Oracle SQL Developer or PL/SQL works.在 Oracle SQL Developer 或 PL/SQL 中执行查询。 Also from visual studio server exporer works.也来自visual studio server exporer 作品。 A window pops up asking for the parameter, typed as VARCHAR2 and it executes the query fine.弹出一个 window 询问参数,键入为 VARCHAR2 并执行查询正常。

I Tried everything.我什么都试过了。 Changing type from Int16, Int32, VARCHAR2 with various length for testing purposes, based also on the Oracle .NET type guide , which states that Int16 is for number of lenght 4, which is the year in my case.出于测试目的,从 Int16、Int32、VARCHAR2 更改类型,具有不同的长度,也基于Oracle .NET 类型指南,该指南指出 Int16 是长度为 4 的数字,在我的例子中是一年。 Nothing.没有什么。

I've also tried to retrieve SQL query history by using what is shown in this stackoverflow question , to discover that apparently, queries fired from outside don't get logged.我还尝试使用此 stackoverflow question 中显示的内容来检索 SQL 查询历史记录,以发现从外部触发的查询显然不会被记录。 I can't find them with this query.我无法通过此查询找到它们。

The only way it works is by directly concatenating the value in the query:它工作的唯一方法是直接连接查询中的值:

builder.Append(@$" WHERE CA.SOME_DATE BETWEEN TO_DATE(CONCAT('0101', '{THE_YEAR}'),'DDMMYYYY') 
            AND TO_DATE(CONCAT('3112', '{THE_YEAR}'),'DDMMYYYY') ");

But I would like to use parameters to avoid SQL injection.但是我想用参数来避免 SQL 注入。

What am I doing wrong?我究竟做错了什么?

Better use更好的使用

builder.Append(@$" WHERE CA.DATE_TO_FILET BETWEEN :aDate AND :bDate");

cmd.Parameters.Add("aDate", OracleDbType.Date, ParameterDirection.Input).Value = new DateTime(THE_YEAR, 1, 1);
cmd.Parameters.Add("bDate", OracleDbType.Date, ParameterDirection.Input).Value = new DateTime(THE_YEAR, 12, 31);

            

CONCAT concatenates two strings, so THE_YEAR should be a string of four characters and not an integer. CONCAT 连接两个字符串,因此 THE_YEAR 应该是四个字符的字符串,而不是 integer。 Have you tried你有没有尝试过

cmd.Parameters.Add("THE_YEAR", OracleDbType.Varchar2, 4, THE_YEAR.ToString(), ParameterDirection.Input);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Oracle.ManagedDataAccess.Client.OracleException (0x80004005): 连接请求超时 - Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Connection request timed out Oracle.ManagedDataAccess.Client.OracleException:“ORA-01843:无效月份” - Oracle.ManagedDataAccess.Client.OracleException: "ORA-01843: not a valid month" Oracle.ManagedDataAccess.Client.OracleException-ORA-01722:无效的数字 - Oracle.ManagedDataAccess.Client.OracleException - ORA-01722: invalid number Oracle.DataAccess.Client.OracleException 0x80004005 - Oracle.DataAccess.Client.OracleException 0x80004005 Oracle.ManagedDataAccess.Client.OracleException:&#39;ORA-02180:CREATE TABLESPACE的无效选项&#39; - Oracle.ManagedDataAccess.Client.OracleException: 'ORA-02180: invalid option for CREATE TABLESPACE' ODP.NET Oracle.ManagedDataAccess导致ORA-12537网络会话结束文件 - ODP.NET Oracle.ManagedDataAccess causes ORA-12537 network session end of file Oracle.ManagedDataAccess.Client.OracleException: &#39;ORA-01830: 日期格式图片在转换整个输入字符串之前结束&#39; - Oracle.ManagedDataAccess.Client.OracleException: 'ORA-01830: date format picture ends before converting entire input string' Oracle Client vs ODP.NET是ASP.NET应用程序 - Oracle Client vs ODP.NET is ASP.NET Application ASP.NET Core 0x80004005 - ASP.NET Core 0x80004005 OracleException(0x80004005)连接到Oracle数据库时 - OracleException (0x80004005) When Connecting to Oracle Database
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM