【问题标题】:Weird behavior. Parameter for date column in oracle db奇怪的行为。 oracle db中日期列的参数
【发布时间】:2021-04-05 07:53:16
【问题描述】:

我在 Oracle12 中遇到了这种奇怪的行为。我在 VisualStudio 2019 中使用 oracle.managed.dataAccess

情况如下: 我正在使用一个参数变量(默认情况下是一个字符串),但我没有得到任何结果。该语句本身有效(没有错误),但由于 date 参数,我没有得到任何数据库条目。 date_column 是数据库中的日期类型。

string sql = "select * from Table where c_id = :myC_id and date_column > to_date(:myDate, 'yyyy-mm-dd hh24:mi:ss')";

OracleCommand cmd = new OracleCommand();
cmd.Connection = connectionstring;
cmd.CommadnText = sql;
cmd.Parameters.Add(new OracleParameter("myC_id",myC_id)); 
cmd.Parameters.Add(new OracleParameter("myDate",myDate)); 

我尝试将参数作为字符串、日期和所有内容。来回转换了,还是不行。但是,如果我将日期硬编码为下面的字符串,它就可以工作。我正在获取结果和数据。

string sql = "select * from Table where c_id = :myC_id and date_column > to_date('2021-03-30 09:00:00', 'yyyy-mm-dd hh24:mi:ss')";

如果我将字符串变量连接到下面的 sql 字符串,我也会获取数据。

string myDate = "'" + "2021-03-30 09:00:00" + "'";
string sql = "select * from Table where c_id = :myC_id and date_column > to_date({myDate}, 'yyyy-mm-dd hh24:mi:ss')";

但是它不能与参数一起工作,有人可以告诉我为什么,以及我是如何让它工作的吗?

【问题讨论】:

  • 我不知道您使用的工具,但这肯定是错误的。我猜/希望这是一个错字:yyyy-mm-dd hh23:mi:ss
  • 假设to_date 将字符串日期解析为数据库日期类型,并且C# 中的myDateDateTime,为什么在第一个示例中将:mydate 视为字符串?不是date_column > :myDate吗?
  • edit您的问题包含您定义变量并为其分配值的C#代码。
  • 错字? hh23 而不是 hh24
  • 您需要截断小时分钟和秒吗?你需要 >= 而不是 >?

标签: c# .net oracle frameworks


【解决方案1】:

以下示例应该对您有所帮助。

设置

create table tableX (id number(10), c_id number(10), date_column date );

insert into tableX (id, c_id,date_column) values (1,1,to_date('2021-09-09 08:00:00', 'yyyy-mm-dd hh24:mi:ss'));
insert into tableX (id, c_id,date_column) values (2,1,to_date('2021-03-30 08:00:00', 'yyyy-mm-dd hh24:mi:ss'));
insert into tableX (id, c_id,date_column) values (3,2,to_date('2021-09-09 08:00:00', 'yyyy-mm-dd hh24:mi:ss'));
insert into tableX (id, c_id,date_column) values (4,2,to_date('2021-03-30 08:00:00', 'yyyy-mm-dd hh24:mi:ss'));

Commit;

示例

using var con = new OracleConnection(conString);
using var cmd = con.CreateCommand();
con.Open();

int myC_id = 2;

var dateAsString = "2021-03-30 09:00:00";
var culture = CultureInfo.CreateSpecificCulture("fr-FR");
var styles = DateTimeStyles.AssumeLocal;

DateTime myDate = DateTime.Parse(dateAsString, culture, styles);

//DateTime myDate = new DateTime(2021, 3, 30, 9, 0, 0); //2021-03-30 09:00:00

cmd.CommandText = "select id, c_id, date_column from tableX where c_id = :myC_id and date_column > :myDate";

cmd.BindByName = true;
cmd.Parameters.Add(new OracleParameter(":myC_id", OracleDbType.Int32, myC_id, System.Data.ParameterDirection.Input));
cmd.Parameters.Add(new OracleParameter(":myDate", OracleDbType.Date, myDate, System.Data.ParameterDirection.Input));

OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
    Console.WriteLine($"Found Row: ID={reader.GetInt32(0)}, C_ID={reader.GetInt32(1)}, DATE_COLUMN={reader.GetDateTime(2)}");
}

输出

Found Row: ID=3, C_ID=2, DATE_COLUMN=09.09.2021 08:00:00

您说date_column 是在数据库中输入日期,而您的输入值myDate 是一个字符串。 我建议在 C# 中将 myDate 转换为 DateTime。对于解析,您必须定义格式提供程序。见https://docs.microsoft.com/de-de/dotnet/api/system.datetime.parse

您的日期字符串看起来像fr-FR

在您的示例中,您使用 SQl-Statment 中的参数 :myC_idmyC_id 作为 OracleParameter 名称。您必须使用相同的名称。

我会推荐设置属性cmd.BindByName = true。默认值为 false,参数由位置而非名称绑定。按位置表示代码中cmd.Parameters.Add() 的顺序和数量必须与SQL 语句中的绑定参数顺序相同。

【讨论】:

  • 感谢您的回答,一天后我用几件事解决了这个问题。使用 OracleDbType.Date 将字符串日期解析为 DateTime,并将 BindByName 设置为 true。
猜你喜欢
  • 2015-10-28
  • 1970-01-01
  • 2015-05-11
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 2020-05-02
  • 1970-01-01
  • 2014-03-18
相关资源
最近更新 更多