Oracle процедура увеличения даты - PullRequest
0 голосов
/ 24 января 2020

Я пытаюсь увеличить дату на основе условия (в то время как дата больше, чем другое):

CREATE OR REPLACE PROCEDURE schema.procedura
 AS

dt_lst DATE;
dt_md  DATE;
eu_val INT;

BEGIN

  for i in (select rowid, TABLELORIK.* from TABLELORIK)

LOOP

   dt_md  := to_date('20290401','YYYYMMDD');
   dt_lst := to_date('20190802','YYYYMMDD');
   eu_val := 180

 while  dt_md > dt_lst 
  LOOP
   dt_lst := dt_lst + eu_val;
  END LOOP;

  UPDATE TABLELORIK set DATE_COL = to_char(dt_lst,'YYYYMMDD') where rowid=i.rowid;
  COMMIT;

END LOOP;
END procedura;
/

В этом случае мой желаемый результат - DATE_COL = 20281212 (который на самом деле меньше что dt_md и l oop должны на этом остановиться!)

Каков мой вывод l oop в этом случае: 20290610 (дополнительные +180 дней (еще один шаг l oop и теперь условие) dt_md> dt_lst не работает))

Может ли кто-нибудь помочь мне с этим последним шагом остановить l oop и не передавать dt_md.

Ответы [ 2 ]

3 голосов
/ 24 января 2020

Вам не нужен ни l oop в вашем коде, ни использование PL / SQL.

. Вы можете вычислить целевую дату напрямую:

select to_date('20190802','YYYYMMDD')
  + 180 * trunc((to_date('20290401','YYYYMMDD') - to_date('20190802','YYYYMMDD'))/180)
from dual;

TO_DATE('2
----------
2028-12-12

или с литералами даты:

select date '2019-08-02' + 180 * trunc((date '2029-04-01' - date '2019-08-02')/180)
from dual;

Разница между двумя датами - это число или дни. date '2029-04-01' - date '2019-08-02' дает вам 3530. Вы хотите знать, сколько полных кратных 180 вписывается в это, так что разделите на 180, что дает 19.6111 ...; укоротить это до 19; умножьте это на 180, чтобы получить фактическое количество дней, которое вы хотите, 3420; и, наконец, добавьте это к дате начала.

А затем обновите сразу все строки в вашей таблице:

update TABLELORIK
set date_col = date '2019-08-02' + 180 * trunc((date '2029-04-01' - date '2019-08-02')/180);

Если ваш столбец действительно является строкой, оберните его в to_char(), но вы не должны хранить даты в виде строки.

Вы можете сделать это в процедуре, но, похоже, нет особого смысла.

Даже если это присваивание инкремента в al oop, вам не нужно обновлять каждую строку в таблице один за другим; и вам не нужно каждый раз пересчитывать dt_lst (если только задание не предназначено для корректировки исходного значения столбца, а не для одной и той же фиксированной даты):

CREATE OR REPLACE PROCEDURE procedura
AS

  dt_lst DATE;
  dt_md  DATE;
  eu_val INTEGER;

BEGIN

  dt_md  := date '2029-04-01';
  dt_lst := date '2019-08-02';
  eu_val := 180;

  while dt_lst + eu_val <= dt_md
  LOOP
    dt_lst := dt_lst + eu_val;
  END LOOP;

  UPDATE TABLELORIK set DATE_COL = dt_lst;

END procedura;
/

insert into TABLELORIK (id, date_col) values (1, sysdate);
insert into TABLELORIK (id, date_col) values (2, null);

exec procedura;

select * from TABLELORIK;

        ID DATE_COL  
---------- ----------
         1 2028-12-12
         2 2028-12-12
1 голос
/ 24 января 2020

Если вы хотите, чтобы ваш while l oop прекратил до того, как dt_lst больше, чем dt_md, вы должны это сказать. Попробуйте это:

while dt_md > dt_lst + eu_val
...