ODP.NET:Oracle.ManagedDataAccess.Client.OracleException(0x80



尝试使用带有C#.NET 5 web应用程序的Oracle.ManagedDataAcces.Client(ODP.NET(执行选择。

Oracle.ManagedDataAcces.Client版本是截至2021年6月2日的最新3.21.1版本。

错误:

Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware1执行请求时发生未经处理的异常。Oracle.ManagedDataAccess.Client.OracleException(0x80004005(:ORA-01841:(完整(年份必须介于-4713和+99999之间,而不是0位于OracleInternal.ServiceObjects.OracleConnectionImpl.VerifyExecution(Int32&cursorId,布尔bThrowArrayBindRelatedErrors,SqlStatementType SqlStatementType,Int32 arrayBindCount,OracleException&exceptionForArrayBindDML,布尔&hasMoreRowsInDB,布尔bFirst迭代完成(

这是查询代码

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;
}
}

在Oracle SQL Developer或PL/SQL中执行查询是可行的。同样来自visualstudio服务器exporer作品。弹出一个窗口,要求输入参数VARCHAR2,并执行查询。

我什么都试过了。出于测试目的,还基于Oracle.NET类型指南,从Int16、Int32、VARCHAR2更改类型,该指南指出Int16代表长度为4的数字,在我的情况下是年份。没有什么

我还试图通过使用这个stackoverflow问题中显示的内容来检索SQL查询历史记录,以发现显然,从外部发出的查询不会被记录。我用这个查询找不到它们。

它的唯一工作方式是直接连接查询中的值:

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

但是我希望使用参数来避免SQL注入。

我做错了什么?

更好地使用

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连接两个字符串,因此THE_YEAR应该是一个由四个字符组成的字符串,而不是整数。你试过吗

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

相关内容

  • 没有找到相关文章

最新更新