Использование SYSDATE () без таблицы DUAL - PullRequest
1 голос
/ 23 мая 2019

Я удивлен, что этот вопрос не был задан. Я, должно быть, здесь упускаю что-то очень очевидное, и я готов ко всем отрицательным голосам и 3-секундному ответу.

В MSSQL вы можете вызывать GETDATE() без необходимости зависеть от таблицы базы данных, но в Oracle SYSDATE должно исходить из DUAL. Нет ли способа получить текущую дату в Oracle без необходимости проходить через DUAL?

EDIT

Очевидно, что это не имеет ничего общего с 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)

Выше не будет работать, и из ответов здесь кажется, что добавление двойного туда не рекомендуется. Какое здесь самое оптимальное решение?

Ответы [ 4 ]

1 голос
/ 23 мая 2019

Избегайте write () после sysdate.

Пример - использование CASE в предложении WHERE (без использования 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

1 голос
/ 23 мая 2019

Вы можете просто использовать SYSDATE без какой-либо явной ссылки на таблицу DUAL.

Что-то вроде этого: INSERT INTO SOME_TABLE(some_date) VALUES (SYSDATE)

Добро пожаловать в Oracle, где все сбивает с толку и противоречит здравому смыслу.

1 голос
/ 23 мая 2019

Нет ли способа получить текущую дату в Oracle без необходимости проходить через DUAL?

Sysdate - это псевдостолбец, который мы можем рассматривать как функцию, которая возвращаеттекущая дата и времяТак что его можно использовать как любую другую функцию.Да, в проекции запроса, например ...

 select sysdate from dual;

... или ...

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

Но также и в предложении where.Сотрудники, принятые на работу за последние тридцать дней:

 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;
1 голос
/ 23 мая 2019

Ваш вопрос о sysdate, но на самом деле он не имеет ничего общего с sysdate.

В Oracle для всех запросов select требуется условие from. В предложении from есть , чтобы что-то содержать. Так, однажды кто-то из Oracle изобрел dual вместе со своим очень неловким именем как встроенную таблицу с ровно одной строкой. Википедия даже имеет запись на эту тему.

Не для всех баз данных требуется условие from для select - например, для SQL Server, MySQL и Postgres все разрешают select без такового.

Вы можете использовать скалярное выражение, например sysdate, в любом месте запроса, где разрешено скалярное выражение. Вы можете повторять это столько раз, сколько хотите, совершенно независимо от того, что содержится в предложении from.

Вы можете встроить скалярное выражение в подзапрос в любой базе данных. Например,

select (select sysdate from dual)
from dual

и

select (select getdate())

Оба допустимые выражения. Тем не менее, это почти всегда плохая практика, и ее почти всегда следует избегать. (Единственное исключение, о котором я могу подумать, это использование константы в предложении упорядочивания оконных функций в SQL Server для предотвращения издержек сортировки, таких как row_number() over (order by (select null))).

...