使用不带DUAL表的SYSDATE()

时间:2019-05-23 17:14:16

标签: sql oracle sysdate

我很惊讶没有提出这个问题。我必须在这里遗漏一些非常明显的东西,我已经准备好接受所有否决票和3秒的答案。

在MSSQL中,您可以调用GETDATE(),而不必依赖数据库表,但是在Oracle SYSDATE中,必须来自DUAL。不必通过DUAL来获取Oracle中的当前日期吗?

编辑

很显然,这与SYSDATE没有多大关系,而更多与我对它的错误使用有关。请参见以下WHERE子句:

WHERE (extract(YEAR from ORDER_DATE) = (case when extract(month from SYSDATE()) < 11 then extract(year from SYSDATE()) else extract(year from SYSDATE())+1 end)

上面的方法不起作用,从这里的答案来看,似乎不建议在其中添加double。最好的解决方案是什么?

4 个答案:

答案 0 :(得分:1)

您的问题与sysdate有关,但实际上与sysdate无关。

在Oracle中,所有select查询都需要一个from子句。 from子句必须包含某些内容。因此,曾几何时,Oracle的某人发明了dual及其非常笨拙的名称,作为一个只有一行的内置表。 Wikipedia甚至有关于这个主题的条目。

并非所有数据库都需要from的{​​{1}}子句-例如,SQL Server,MySQL和Postgres都允许select不带子句。

您可以在允许使用标量表达式的查询中的任何位置使用标量表达式,例如select。您可以根据自己的喜好重复多次,而与sysdate子句中的内容完全无关。

可以将标量表达式嵌入任何数据库的子查询中。例如,

from

和:

select (select sysdate from dual)
from dual

都是有效的表达式。但是,这几乎始终是不好的做法,应该几乎始终避免这样做。 (我想到的一个例外是在SQL Server的窗口函数排序子句中使用常量以防止进行排序,例如select (select getdate()) 。)

答案 1 :(得分:1)

您可以直接使用SYSDATE,而无需显式引用DUAL表。

与此类似的东西: INSERT INTO SOME_TABLE(some_date) VALUES (SYSDATE)

欢迎来到Oracle,那里的一切令人困惑并且与常识背道而驰。

答案 2 :(得分:1)

  

是否无需经过DUAL就无法获取Oracle中的当前日期?

Sysdate是一个伪列,我们可以将其视为返回当前日期时间的函数。因此它可以像其他任何功能一样使用。是的,在查询投影中,例如...

 select sysdate from dual;

...或...

insert into sometable (id, date_created)
values (id_seq.nextval, sysdate);

而且在where子句中。最近30天雇用的员工:

 select * from emp
 where hire_date > sysdate - 30

要找到今年被录用的员工,我们可以这样做:

 select * from emp
 where extract(year from hire_date) = extract(year from sysdate)

...但这可能会更好

 select * from emp
 where hire_date >= trunc(sysdate, 'YYYY') -- resolves to 2019-01-01
 /

在PL / SQL中:

declare
    ld date;
begin
    ld := trunc(sysdate); 
end;

答案 3 :(得分:1)

避免在sysdate之后写()。

示例-在WHERE子句中使用您的CASE(不使用DUAL):

create table T ( dt date ) ;

insert into T ( dt ) values ( sysdate ) ;


-- just write SYSDATE, not SYSDATE()
select *
from T   
where ( extract ( year from dt ) ) = ( 
  case 
    when extract( month from sysdate ) < 11 then
      extract( year from sysdate ) 
    else
      extract( year from sysdate ) + 1
  end 
) ;

-- output
DT       
---------
23-MAY-19

DBfiddle