奇怪的行为。 oracle db

时间:2021-04-05 07:53:16

标签: c# .net oracle frameworks

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

情况如下: 我正在使用一个参数变量(默认情况下是一个字符串),但没有得到任何结果。该语句本身有效(没有错误),但由于日期参数的原因,我没有得到任何 db 条目。 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')";

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

1 个答案:

答案 0 :(得分:0)

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

设置

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_id,并使用 myC_id 作为 OracleParameter 名称。您必须使用相同的名称。

我建议设置属性 cmd.BindByName = true。默认值为 false,参数受位置约束,而不是受名称约束。位置意味着代码中 cmd.Parameters.Add() 的顺序和数量必须与 SQL 语句中的绑定参数的顺序相同。

相关问题