将日期时间转换为字符串格式并将其传递给查询
Posted
技术标签:
【中文标题】将日期时间转换为字符串格式并将其传递给查询【英文标题】:convert datetime in string format and pass it to query 【发布时间】:2021-01-09 08:29:33 【问题描述】:我有一个查询,我以下面给出的格式传递值,它在 oracle pl/sql 中工作
Select ASE_ID
from ASE_DTLS a
where TO_CHAR(CRT_ON,'YYYY-MM-DD')
between '2020-09-01' and '2020-09-23'
上面的查询给出了输出。但是当我试图以下面给定的格式通过 c# 查询传递它时,它没有返回值。
Select ASE_ID
from ASE_DTLS a
where TO_CHAR(CRT_ON,'YYYY-MM-DD')
between :CRT_ON and :CRT_ON";
从 '01-09-2020 00:00:00' 和 '23-09-2020 00:00:00' 格式的 fieldval[0] 中的 post 方法接收值。
command.Parameters.Add(":CRT_ON", fieldval[0].From.ToString("yyyy-MM-dd"));
command.Parameters.Add(":CRT_ON", fieldval[0].To.ToString("yyyy-MM-dd"));
通过 ExecuteReader 读取它时获得 0 条记录。 From & To 与 c# 中的定义相同
public DateTime From get; set;
public DateTime To get; set;
和 CRT_ON 在 oracle 中作为日期。
【问题讨论】:
日期没有格式,它们是二进制值,在 .NET 和 Oracle 中都是如此。 不要将它们作为字符串传递给数据库。请改用日期类型的参数。TO_CHAR
是个大bug,导致数据库无法使用索引
command.Parameters.Add(":CRT_ON", SqlDbType.DateTime).Value = fieldval[0].From;
还有其他严重的错误,比如在 .NET 和查询中两次使用 same 参数名称 这不会抛出吗?充其量,查询将返回错误的结果
SQL 查询应该类似于select ... where CRT_ON between :CRT_FROM and :CRT_TO
。在 .NET 中,参数应命名为 :CRT_FROM
和 :CRT_TO
您不需要将每个参数都转换为字符串。
【参考方案1】:
.NET 和 Oracle 中的日期都没有格式,它们是二进制值。查询应该使用与日期相关类型的参数,而不是将日期转换为字符串,而只是将它们转换回日期。
代码也有其他问题 - 相同的参数被添加了两次,但值不同。查询本身使用BETWEEN
子句中的单个参数,有效地将其转换为相等检查。
查询应该是:
Select ASE_ID
from ASE_DTLS a
where CRT_ON between :CRT_FROM and :CRT_TO
参数的类型应该是DateTime
:
var fld=fieldval[0];
command.Parameters.Add(":CRT_FROM", OracleDbType.Date).Value = fld.From.Date;
command.Parameters.Add(":CRT_TO", OracleDbType.Date).Value = fld.To.Date;
DateTime.Date 仅返回 DateTime 值的日期部分。
如果CRT_ON
是date
,这将按原样工作。如果它是 timestamp
,则查询将在 00:00 返回最多到 :CRT_TO
的行。要返回当天的日期,查询必须更改为
Select ASE_ID
from ASE_DTLS a
where CRT_ON >= :CRT_FROM and CRT_ON < :CRT_TO
而:CRT_TO
应该增加一天:
var toParam=command.Parameters.Add(":CRT_TO", SqlDbType.DateTime);
toParam.Value = fld.To.Date.AddDays(1);
【讨论】:
我试过但得到错误 ORA-01858:在需要数字的地方发现了一个非数字字符。在 oracle 中还有一件事只有 OracleDbType.Date 而不是 OracleDbType.DateTime 试过什么?只有当您使用字符串插值而不是参数时,您才会收到这样的错误。或者将字符串而不是 DateTime 传递给参数。至于OracleDbType
- 您没有指定您使用的提供商。它可能是通用的 ODBC 或 OLEDB 提供者、Oracle 自己的胖提供者、第三方提供者。正确的类型也可能取决于字段 - 是 date
还是 timestamps
【参考方案2】:
您应该使用日期作为date
。不要将其转换为char
。
Select ASE_ID from ASE_DTLS a where trunc(CRT_ON) between to_date('2020-09-01','YYYY-MM-DD') and to_date('2020-09-23','YYYY-MM-DD')
【讨论】:
那个 SQL 查询不使用参数。如果是这样,就不需要 TO_DATE @PanagiotisKanavos 根据您的本地设置可能需要(如果默认日期格式不同) 不,不是。日期是二进制值。你在反驳你自己的答案。如果不转换为char,为什么还要将参数值转换为日期? 这是唯一的问题 - 使用了错误的类型。如果使用正确的类型,则无需转换。如果不使用Datetime
,无论如何答案都是错误的。您必须使用与查询相同的格式将日期转换为 .NET 中的字符串,否则可能会导致查询失败或得到错误的结果
@DikshaKumari 是的,Panagiotis 是对的——如果你使用 OracleDbType.Date
,那么你不应该在 sql 中使用 to_date
。使用这样的东西:Select ASE_ID from ASE_DTLS a where trunc(CRT_ON) between :CRT_ON_FROM and :CRT_ON_TO
(我用 2 个变量 :CRT_ON_FROM
和 :CRT_ON_TO
替换了你的 :CRT_ON
)以上是关于将日期时间转换为字符串格式并将其传递给查询的主要内容,如果未能解决你的问题,请参考以下文章
Java 日期格式:字符串到 XMLGregorianCalendar