Вам не нужен ни 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