【问题标题】:Oracle Date Comparison Issue Totally confused - what am I doing wrong?Oracle 日期比较问题完全困惑 - 我做错了什么?
【发布时间】:2013-12-27 14:32:41
【问题描述】:

我是新手,正在学习 Oracle。我想比较函数中的日期,在实现函数时我遇到了输出错误并且没有得到有效答案的问题我搜索了很多解决方案但徒劳无功....

目前我找到的解决方案是:

  1. 不要比较日期时间和日期。

  2. 如果使用 DateTime,则需要先 TRUNC 以去除时间因素。

  3. 比较日期时首先将日期转换为 To_char(anyDate,'dd-mon-yyyy');

  4. 如果我们比较像 1-dec-13 和 27-dec-13 这样的日期,请确保两个年份相同。两者都应该是 2013 年的。

到目前为止,我已经通过了所有的限制,但未能找到解决方案。有谁能够帮我。我在做什么错误?提前感谢您的期待。

 SET serveroutput on;
 DECLARE
 startDate DATE := to_date('1'|| '/' ||to_char(sysdate, 'MM')  || '/2013','DD/MM/YYYY'); 
 secDate DATE :=to_date(SYSDATE, 'DD/MM/YYYY ');

 BEGIN

   DBMS_OUTPUT.PUT_LINE( 'if secDate  '|| secDate ||' is Greater Then'); 
   DBMS_OUTPUT.PUT_LINE( 'StartDate '|| startDate || ' Output = ' );   

   if(secDate>startDate)
    then
    DBMS_OUTPUT.PUT_LINE('True' ); 
    else    
    DBMS_OUTPUT.PUT_LINE('false'); 

   end if;
end;

【问题讨论】:

  • I got an issue 有什么问题?
  • @NicholasKrasnov 我已经编辑了这个问题。
  • 您期望 pl/sql 块应该“打印”什么? that output is wrong and not getting a valid answer 什么是适合您的输出?输出很可能是true。你期望它是什么?
  • 如果 secDate 是 > 那么 startDate 它应该打印 true 不是吗???
  • @YOusaFZai 是的,但现在它打印了false。看看我的回答为什么。

标签: oracle plsql


【解决方案1】:

您的积分顺序:

i Oracle DATE 保存日期和时间,精确到秒。您可以比较它们,例如12/27/2013 00:00:00 小于12/27/2013 09:00:00

ii 如果您想查看两个带有时间分量的DATE 值(例如12/27/2013 14:00:0012/27/2013 12:34:56)是否在同一天,那么是的,您需要@987654327 @:IF TRUNC(firstDate) = TRUNC(secondDate).

iii 使用TO_CHAR 比较DATE 值没有任何好处。如果您不想在比较中包含时间,请使用TRUNC;如果您需要时间,请忽略它。

iv 年份不必相同。像12/27/2013 这样的日期大于12/27/2012 并且小于12/27/2014。如果您将其保留为 DATE 类型,Oracle 会做正确的事情。

至于你的代码出了什么问题,看看你的startDate初始化:

'1'|| '-' ||to_char(sysdate, 'MM')  || '2013'

今天,这将为您提供1-122013,它与TO_DATE 调用中的格式字符串DD/MM/YYYY 不匹配。这就是为什么你没有得到一个像样的约会。

如果要获取当月的第一天,Oracle 提供了一个方便的快捷方式:

startDate := TRUNC(SYSDATE, 'MONTH');

所以我会忘记所有格式并使用这样的东西;注意它是多么简单:

SET serveroutput on;
DECLARE
  startDate DATE := TRUNC(SYSDATE, 'MONTH');
  secDate DATE := SYSDATE;
BEGIN
  DBMS_OUTPUT.PUT_LINE( 'if secDate  '|| secDate ||' is Greater Then'); 
  DBMS_OUTPUT.PUT_LINE( 'StartDate '|| startDate || ' Output = ' );   

  if(secDate>startDate) then
    DBMS_OUTPUT.PUT_LINE('True' ); 
  else    
    DBMS_OUTPUT.PUT_LINE('false'); 
  end if;
END;

请注意,secDate 仅在当月第一天的午夜等于 startDate,此时两个值(对于 2013 年 12 月)将是 12/27/2013 00:00:00。在一个月的所有其他时间,secDate 会更大。

请注意,我使用12/27/2013 00:00:00 来解释 2013 年 12 月 27 日午夜。这只是为了让我可以用英语解释日期。这不是 Oracle 存储日期的方式。 Oracle 如何存储日期?这并不重要 - 重要的是,如果您将日期保留为 DATE 格式并在您只关心日期而不关心时间时使用 TRUNC,Oracle 会很好地处理日期。

【讨论】:

  • Thanx Gibbs 您的解决方案绝对正确,但在我的问题中,我更改了格式并获得相同的输出,只需查看已编辑的问题。
  • 你得到什么输出?关于secDate DATE := to_date(SYSDATE, 'DD/MM/YYYY ') 的一些注意事项:您调用to_date 的值已经 是一个日期。这可能很棘手,因为 Oracle 需要 char,因此它将 SYSDATE 转换为 char,并使用其默认日期格式执行此操作。如果您的默认日期格式不是DD/MM/YYYY,则转换将不起作用。要从日期中删除时间,总是使用TRUNC,因为它不依赖日期格式作为特定值。我只是工作。仅使用 TO_CHAR 格式化日期,而不是用于操作它们。
【解决方案2】:

to_date(SYSDATE, 'DD/MM/YYYY ') 那是你的问题。结果它给出了27.12.0013。这就是为什么您会打印出false。实际上,您不需要将sysdate 转换为日期,因为它已经是日期类型。改用这个:

secDate DATE := SYSDATE;

【讨论】:

    【解决方案3】:

    看到这条线to_date('1'|| '-' ||to_char(sysdate, 'MM') || '2013','DD/MM/YYYY');

    '1'|| '-' ||to_char(sysdate, 'MM') || '2013' 给你'1-122013',所以你 to_date('1-122013','DD/MM/YYYY');

    格式不匹配,你也得换一个

    to_date('01/'|| to_char(sysdate, 'MM')|| '/2013','DD/MM/YYYY');

    to_date('01'|| '-' ||to_char(sysdate, 'MM')|| '2013','DD-MMYYYY')

    而不是secDate DATE :=to_date(SYSDATE, 'DD/MM/YYYY ');,只需使用secDate DATE :=TRUNC(SYSDATE);,不需要转换。

    【讨论】:

    • 我已经编辑了这个问题。我已经尝试过相同的格式。它不是解决方案。
    • The format don't match 不太正确。当您将字符串文字转换为 date 数据类型的值时,使用什么字符作为分隔符并不重要。 to_date('01-122013', 'dd/mm/yyyy')to_date('01.12.2013', 'dd/mm/yyyy') 一样有效,与to_date('01/12/2013', 'dd/mm/yyyy') 一样有效
    猜你喜欢
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    • 2017-03-24
    相关资源
    最近更新 更多