powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Interval data type
17 сообщений из 17, страница 1 из 1
Interval data type
    #39950477
endy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет. Пожалуйста помогите с решением данного вопроса. Как бы я не пытался не могу получить нужную информацию.

Мне нужно совершить арифметическую операцию с типом данных interval и получить необходимый результат.

Код: plsql
1.
2.
3.
SELECT SYSDATE,
        to_char(to_date(SYSDATE, 'DD-MON-RR HH24:MI') + INTERVAL '1' MONTH + INTERVAL '1' DAY - INTERVAL '3' SECOND, 'DD-MON-RR HH24:MI') now
FROM   dual;



Такой запрос выдает такой аутпут:

Код: plsql
1.
23-APR-20	23-MAY-20 23:59



Но мне нужно чтобы в аутпуте появилась информация о секунде, также необходимо чтобы был результат не конец дня а нынешнее время.
При использовании такого запроса

Код: plsql
1.
2.
3.
SELECT SYSDATE,
        to_timestamp(SYSDATE + INTERVAL '1' MONTH + INTERVAL '1' DAY - INTERVAL '3' SECOND) now
FROM   dual;



аутпут выдает такой результат:

Код: plaintext
1.
23-APR-20	24-MAY-20 00:00:00.000000000
Тоесть в первом запросе результат конец дня, а во втором начало дня. Но мне нужно время без округления. Спасибо заранее всем кто помогает.

Модератор: научитесь в конце концов использовать тег SRC
...
Рейтинг: 0 / 0
Interval data type
    #39950485
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
endy,

Типы date и interval несовместимы.
"+ INTERVAL '1' MONTH" - опасная операция.
...
Рейтинг: 0 / 0
Interval data type
    #39950487
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
endy
Код: plsql
1.
2.
3.
SELECT SYSDATE,
        to_char(to_date(SYSDATE, 'DD-MON-RR HH24:MI') + INTERVAL '1' MONTH + INTERVAL '1' DAY - INTERVAL '3' SECOND, 'DD-MON-RR HH24:MI') now
FROM   dual;



1. Вот так: to_date(SYSDATE, 'DD-MON-RR HH24:MI')
вообще не пишите. Никогда.

endy

Но мне нужно чтобы в аутпуте появилась информация о секунде,

Код: plsql
1.
 to_char(..., 'DD-MON-RR HH24:MI:SS') now


endy

также необходимо чтобы был результат не конец дня а нынешнее время.

Тогда просто SYSDATE или CURRENT_DATE - о разнице прочтете в документации.
Тезис: нельзя к нынешнему времени прибавить месяц и получить нынешнее время.

По арифметике:
Код: plsql
1.
2.
3.
4.
5.
SELECT SYSDATE
     , to_char(add_months(SYSDATE,1) + 1 - 3/86400, 'DD-MON-RR HH24:MI:SS') now
     , to_char(systimestamp+ INTERVAL '1' MONTH + INTERVAL '1' DAY - INTERVAL '3' SECOND, 'DD-MON-RR HH24:MI:SS') now
     --, to_char(timestamp'2020-01-30 00:00:00.00'+ INTERVAL '1' MONTH, 'DD-MON-RR HH24:MI:SS') now --ORA-1839
FROM   dual;


+interval 1 month - операция кривая, с ней можно работать только с датами начала месяца, пустите в продуктив - подорвется, придется переделывать.
...
Рейтинг: 0 / 0
Interval data type
    #39950565
endy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous

Тезис: нельзя к нынешнему времени прибавить месяц и получить нынешнее время.


Приношу свои извинения. Я не правильно выразился. Я имел ввиду что мне необходимо получить не сегодняшний день, а тоже самое время в следующем месяце.
Допустим сейчас 16:58 23 апреля, мне нужно получить время 16:58 23 мая, но никак не 00:00 или 23:59
...
Рейтинг: 0 / 0
Interval data type
    #39950578
iehf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
endy,
попробуйте add_months()
тут
...
Рейтинг: 0 / 0
Interval data type
    #39950581
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
endy
тоже самое время в следующем месяце.

Невозможно - Вы вычитаете 3 секунды.
И вот еще: что Вы ожидаете получить, добавляя месяц к 30 и 31 числу?
...
Рейтинг: 0 / 0
Interval data type
    #39950590
iehf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,
самому стало интересно :)
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
alter session set nls_date_format='dd-mm-yyyy hh24:mi:ss';
select sysdate, add_months(sysdate,1),add_months(sysdate,-1) from dual;
23-04-2020 16:26:31	23-05-2020 16:26:31	23-03-2020 16:26:31

select add_months('31-01-2020 16:26:31',1) from dual;
29-02-2020 16:26:31
select add_months('31-01-2019 16:26:31',1) from dual;
28-02-2019 16:26:31



видимо, дает последний день следующего месяца с учетом года
...
Рейтинг: 0 / 0
Interval data type
    #39950593
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
endy,

Вы неправильно поняли

to_date(SYSDATE - зависит от NLS
часто "ошибка", неявное преобразование в строку


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SQL> select sysdate s,to_date(SYSDATE, 'DD-MON-RR HH24:MI') t from dual;
select sysdate s,to_date(SYSDATE, 'DD-MON-RR HH24:MI') t from dual
                         *
ERROR at line 1:
ORA-01843: not a valid month


SQL> ed
Wrote file afiedt.buf

  1* select sysdate s,to_date(SYSDATE, 'DD-MM-RR HH24:MI') t from dual
SQL> /

S          T
---------- ----------
23.04.2020 23.04.2020


если надо обрезать секунды, trunc(sysdate,'mi')

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SQL> ed
Wrote file afiedt.buf

  1  SELECT SYSDATE,
  2          to_char(trunc(SYSDATE, 'MI') + INTERVAL '1' MONTH + INTERVAL '1' DAY - INTERVAL '3' SECOND, 'DD-MON-RR HH24:MI:SS') now
  3* FROM   dual
SQL> /

SYSDATE             NOW
------------------- ------------------
23.04.2020 16:29:38 24-ТРА-20 16:28:57




ps
INTERVAL 'хх' MONTH луче не использовать
22121440 розкоментируйте

....
stax
...
Рейтинг: 0 / 0
Interval data type
    #39950661
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax

INTERVAL 'хх' MONTH луче не использовать


Интeрвальная арифметика с датами/таймстемпами производит действия тоько с теми частями дат/таймстемпов к которым интeрвал относится. INTERVAL '1' MONTH это TEAR TO MONTH интeрвал посему DATE '202-03-31' + INTERVAL '1' MONTH не изменит DAY TO SECOND часть имы получим 31 Апреля:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
SQL> SELECT DATE '202-03-31' + INTERVAL '1' MONTH  FROM DUAL;
SELECT DATE '202-03-31' + INTERVAL '1' MONTH  FROM DUAL
                        *
ERROR at line 1:
ORA-01839: date not valid for month specified


SQL>



А в високосный год:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
SQL> SELECT DATE '2020-02-29' + INTERVAL '1' YEAR FROM DUAL;
SELECT DATE '2020-02-29' + INTERVAL '1' YEAR FROM DUAL
                         *
ERROR at line 1:
ORA-01839: date not valid for month specified


SQL>



SY.
...
Рейтинг: 0 / 0
Interval data type
    #39950720
endy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous
endy
тоже самое время в следующем месяце.

Невозможно - Вы вычитаете 3 секунды.
И вот еще: что Вы ожидаете получить, добавляя месяц к 30 и 31 числу?


Тут дело не столько в том чтобы получить конкретное время, мне просто хочется понять как работает данный запрос. Так как я готовлюсь к экзамену, а среди вопросов есть такие примеры.

Мне просто стало интересно почему аутпут либо обрезает все до 00 или же округляет до конца дня. Альтернативный вариант мне не поможет, так как мне нужно понять именно как работает данный запрос. Я его не сам придумал, а нашел в тестах.

Просто хочу понять почему округляется если я не ввожу нигде trunc или round.
...
Рейтинг: 0 / 0
Interval data type
    #39950725
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
endy,

То, что ты видишь, это всегда не даты, не интервалы и не числа, а строки, полученные из них.
Смотри функции приведения к строке/форматирования в строку и читай про установку используемых ими параметров по умолчанию.
То что тебя интересует называется Setting NLS Parameters
например, здесь:
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/nlspg/setting-up-globalization-support-environment.html#GUID-6475CA50-6476-4559-AD87-35D431276B20
...
Рейтинг: 0 / 0
Interval data type
    #39950738
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
endy
л, а нашел в тестах.

Просто хочу понять почему округляется если я не ввожу нигде trunc или round.


Потому что округления и в помине нет. Хoчешь понять анализируй каждое действие SELECTa (явное и неявное):

to_date(SYSDATE, 'DD-MON-RR HH24:MI')

Какие параметры у TO_DATE? Первый - строка. А что ты подсовываешь? Тип данных возвращаемый SYSDATE есть DATE а не строка. Что делает Oracle при несоответствии типов? Правильно, неявно преобразует. Т.е. результат SYSDATE преобразуется в строку для чего необходимо знать в какой формат преобразовывать. Где взять? Его задает параметр сессии NLS_DATE_FORMAT. Исходя из того что ты привел это DD-MON-YY. Посемуот SYSDATE возмется только 23-APR-20, т.е. в итоге имеем:

to_date('23-APR-20', 'DD-MON-RR HH24:MI')

Ясно что получаем дату началоа дня.

SY.
...
Рейтинг: 0 / 0
Interval data type
    #39950761
endy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY,

Спасибо. Этот момент я понял.

Я проверил без арифметических действий с sysdate и литералом и итог разный. Теперь понятно почему возвращается начало дня.

Этот запрос возвращает нужные минуты и секнуды

Код: plsql
1.
2.
SELECT SYSDATE,
        to_char(to_date('24-APR-20 1:19:56', 'DD-MON-RR HH24:MI:SS'), 'DD-MON-RR HH24:MI:SS') from dual;



Тогда как при использовании sysdate вместо литерала возвращается начало дня.

Например:

Код: plsql
1.
2.
SELECT SYSDATE,
        to_char(to_date(sysdate, 'DD-MON-RR HH24:MI:SS'), 'DD-MON-RR HH24:MI:SS') from dual;



Но всё таки остаётся неясным как решить указанный выше запрос с использованием именно арифметических действий, чтобы я не делал. Возвращается либо начало/конец дня или же в аутпуте дата указывается в формате DD-MON-RR тоесть указанный по умолчанию nls paramentre. Как же решить эту головоломку не поменяв nls parametre по умолчанию и не прибегнув к альтернативному решению...
...
Рейтинг: 0 / 0
Interval data type
    #39950763
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
endyНапример

Не надо писать бред. Даже как пример. Открой документацию и посмотри что возвращает
функция sysdate и что требуется первым параметром функции to_date.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Interval data type
    #39950764
endy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

Здравствуйте. Я просил о помощи так как не смог разобраться с документацией и на практике не получилось. Я написал по теме форума и благодарен всем кто помогает разобраться. Если вас задевает моя тема проходите мимо) Спасибо за понимание.
...
Рейтинг: 0 / 0
Interval data type
    #39950775
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
endy
SY,

Спасибо. Этот момент я понял.
Но всё таки остаётся неясным как решить указанный выше запрос


Напоминает анекдот как в 20тые годы прошлого века в деревне лектор обьяснял мужикам что у них будет электрическй свет вместо керосиновых ламп и как работает электричество. После лекции встает мужик и говорит в общем я все понял, но как керосин по проводам течет убей бог не понимаю. SYSDATE это дата так зачем преобразвывать ее в строку а затем обратно к дате при этом теряя части даты??? Ты тестируешь арифметику дат с интервалами так и бери дату, добавляй/вычитай интервалы и только потом пребразовывай дату результата в строку желаемого формата для вывода на экран:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT  to_char(
                SYSDATE,
                'DD-MON-YYYY HH24:MI:SS'
               ) now,
        to_char(
                SYSDATE + INTERVAL '1' MONTH + INTERVAL '1' DAY - INTERVAL '3' SECOND,
                'DD-MON-YYYY HH24:MI:SS'
               ) now_plus_one_month_and_1_day_less_3_seconds
  FROM  dual
/

NOW                           NOW_PLUS_ONE_MONTH_AND_1_DAY_LESS_3_SECONDS
----------------------------- ---------------------------------------------
23-APR-2020 19:57:27          24-MAY-2020 19:57:24

SQL>



SY.
...
Рейтинг: 0 / 0
Interval data type
    #39950817
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
endy

Тогда как при использовании sysdate вместо литерала возвращается начало дня.

Например:

Код: plsql
1.
2.
SELECT SYSDATE,
        to_char(to_date(sysdate, 'DD-MON-RR HH24:MI:SS'), 'DD-MON-RR HH24:MI:SS') from dual;



Но всё таки остаётся неясным


еще раз зависит от НЛС
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
SQL> alter session set nls_date_format='dd-MON-rr hh24:mi:ss';

Session altered.

SQL> SELECT SYSDATE,
  2          to_char(to_date(sysdate, 'DD-MON-RR HH24:MI:SS'), 'DD-MON-RR HH24:MI:SS') from dual;

SYSDATE            TO_CHAR(TO_DATE(SY
------------------ ------------------
24-КВІ-20 09:21:46 24-КВІ-20 09:21:46

SQL> alter session set nls_date_format='dd-MON-rr';

Session altered.


SQL> SELECT SYSDATE,
  2          to_char(to_date(sysdate, 'DD-MON-RR HH24:MI:SS'), 'DD-MON-RR HH24:MI:SS') from dual;

SYSDATE   TO_CHAR(TO_DATE(SY
--------- ------------------
24-КВІ-20 24-КВІ-20 00:00:00

SQL>



....
stax
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Interval data type
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]