我对Oracle中的日期有一些疑问。
是否可以获得两种DATE类型之间的间隔(以天为单位)?如果是,是否可以在此时间间隔内为每一天做一个声明(例如插入)?
我想过
while (a_sequence != difference_between_dates)
LOOP
a_sequence.next
-- do things
END LOOP;
是否有可能获得具有周期性间隙的间隔? (比如每个周末。例如,Oracle中是否有模运算符?)
我认为像if(a_sequence % 6 || a_sequence % 7)
之类的东西只是在周末做事情(假设较低的日期总是在星期一)。
第二天可以做my_date + 1吗?
答案 0 :(得分:2)
不确定。如果您正在寻找PL / SQL解决方案(您可以在纯SQL中执行它,但它可能有点难以阅读),例如
DECLARE
l_first_date date := date '2015-01-01';
l_last_date date := date '2015-12-31';
l_date_to_check date;
BEGIN
FOR i IN 1 .. l_last_date - l_first_date
LOOP
l_date_to_check := l_first_date + i;
if( to_char( l_date_to_check, 'DY' ) IN ('SAT', 'SUN') )
then
<<do_something>>
end if;
END LOOP;
END;
这假设您的数据库使用的是英语语言环境(不同的语言显然在几天内有不同的缩写)。您可以通过在to_char
函数中指定所需的NLS设置来使代码更加健壮,但对于大多数系统而言,这会增加代码的复杂性,这是不需要的。
答案 1 :(得分:1)
这段代码可以帮助你
DECLARE
first_date DATE := TO_DATE ('01012015', 'DDMMYYYY');
last_date DATE := TO_DATE ('31012015', 'DDMMYYYY');
a_sequence NUMBER := 25;
BEGIN
LOOP
IF a_sequence = last_date - first_date
THEN
EXIT;
END IF;
DBMS_OUTPUT.put_line ('Sequence=' || a_sequence);
a_sequence := a_sequence + 1;
END LOOP;
END;
答案 2 :(得分:-1)
CREATE PROCEDURE `sp_calcula_intervalo`(
IN `p_fl_frequency` VARCHAR(2),
IN `p_dt_start` VARCHAR(10),
IN `p_dt_ends` VARCHAR(10),
OUT `p_qt_ocorrs` INT
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Calculates the interval between two dates'
BEGIN
-- ------------------------------------------------------------------------------
-- This code was written for Mysql
-- ------------------------------------------------------------------------------
-- Calculates the interval between two dates
-- In Weeks, Fortnights, Months, Bimonths, Quarters, Semesters and Years
-- CALL sp_calcula_intervalo('3M', '2020-01-31', '2020-05-31', @p_qt_ocorrs);
-- ------------------------------------------------------------------------------
-- ------------------------------------------------------------------------------
-- Work Variables
-- ------------------------------------------------------------------------------
DECLARE dt_calc DATE DEFAULT NULL;
DECLARE dt_start DATE DEFAULT NULL;
DECLARE dt_ends DATE DEFAULT NULL;
DECLARE dt_proximo_mes DATE DEFAULT NULL;
DECLARE va_result INT DEFAULT 0;
DECLARE va_msg varchar(1000) DEFAULT '';
DECLARE va_end_loop char(1) DEFAULT 'N';
DECLARE va_dd_start char(2) DEFAULT '00';
DECLARE va_mm_start char(2) DEFAULT '00';
DECLARE va_dt_next_mm_calc char(10) DEFAULT '0000-00-00';
DECLARE va_dd_calc char(2) DEFAULT '00';
DECLARE va_mm_calc char(2) DEFAULT '00';
-- ------------------------------------------------------------------------------
-- Values Start
-- ------------------------------------------------------------------------------
SET va_dd_start = SUBSTR(p_dt_start, 9, 2);
SET va_mm_start = SUBSTR(p_dt_start, 6, 2);
SET dt_calc = STR_TO_DATE(p_dt_start,'%Y-%m-%d');
SET dt_start = STR_TO_DATE(p_dt_start,'%Y-%m-%d');
SET dt_ends = STR_TO_DATE(p_dt_ends,'%Y-%m-%d');
SET va_result = 1;
-- ------------------------------------------------------------------------------
-- Loop de Calc
-- ------------------------------------------------------------------------------
WHILE (va_end_loop = 'N') DO
SELECT
CASE p_fl_frequency
WHEN '1M' THEN ADDDATE(dt_calc, INTERVAL 1 MONTH)
WHEN '2M' THEN ADDDATE(dt_calc, INTERVAL 2 MONTH)
WHEN '3M' THEN ADDDATE(dt_calc, INTERVAL 3 MONTH)
WHEN '4M' THEN ADDDATE(dt_calc, INTERVAL 4 MONTH)
WHEN '6M' THEN ADDDATE(dt_calc, INTERVAL 6 MONTH)
WHEN '12M' THEN ADDDATE(dt_calc, INTERVAL 12 MONTH)
WHEN '1W' THEN ADDDATE(dt_calc, INTERVAL 1 WEEK)
WHEN '2W' THEN ADDDATE(dt_calc, INTERVAL 2 WEEK)
END INTO dt_proximo_mes;
SET va_result = va_result + 1;
set va_dt_next_mm_calc = DATE_FORMAT(dt_proximo_mes, '%Y-%m-%d');
SET va_dd_calc = SUBSTR(va_dt_next_mm_calc, 9, 2);
SET va_mm_calc = SUBSTR(va_dt_next_mm_calc, 6, 2);
if p_fl_frequency not in ('1W', '2W') then
if va_dd_calc <> va_dd_start then
if va_mm_calc <> '02' then -- Fevereiro
if va_mm_calc in ('04', '06', '09', '11') then -- Meses com 30 dias
set va_dt_next_mm_calc = concat(SUBSTR(va_dt_next_mm_calc, 1, 8),'30');
else
if va_dd_start = '30' then
set va_dt_next_mm_calc = concat(SUBSTR(va_dt_next_mm_calc, 1, 8),'30');
else
set va_dt_next_mm_calc = concat(SUBSTR(va_dt_next_mm_calc, 1, 8),'31');
end if;
end if;
end if;
end if;
end if;
SET dt_calc = STR_TO_DATE(va_dt_next_mm_calc,'%Y-%m-%d');
if dt_calc >= dt_ends then
set va_end_loop = 'S';
if dt_calc > dt_ends then
SET va_result = va_result - 1;
end if;
end if;
END WHILE;
-- ------------------------------------------------------------------------------
-- Return Calc
-- ------------------------------------------------------------------------------
select va_result as p_qt_ocorrs;
END