在Oracle PL/SQL中使用存储过程插入日期:

huangapple go评论73阅读模式
英文:

Inserting date with procedure in oracle PL/SQL

问题

-- 创建存储过程,向MYTABLE表插入日期数据
CREATE OR REPLACE PROCEDURE FILL_MYTABLE AS
BEGIN
  FOR YEAR_IN_NUMBER IN 2000..2100 LOOP
    FOR MONTH_IN_NUMBER IN 1..12 LOOP
      FOR QUARTER_IN_NUMBER IN 1..4 LOOP
        FOR DAY_IN_NUMBER IN 1..31 LOOP
          -- 计算日期
          DECLARE
            CURRENT_DATE1 DATE;
            CURRENT_QUARTER VARCHAR2(4);
            CURRENT_MONTH NUMBER;
            CURRENT_WEEKDAY VARCHAR2(2);
          BEGIN
            CURRENT_DATE1 := TO_DATE(YEAR_IN_NUMBER || '-' || LPAD(MONTH_IN_NUMBER, 2, '0') || '-' || LPAD(DAY_IN_NUMBER, 2, '0'), 'YYYY-MM-DD');
            CURRENT_QUARTER := 'Q' || QUARTER_IN_NUMBER;
            CURRENT_MONTH := MONTH_IN_NUMBER;
            -- 计算星期几
            CURRENT_WEEKDAY := CASE WHEN TO_CHAR(CURRENT_DATE1, 'D') BETWEEN 2 AND 6 THEN 'YES' ELSE 'NO' END;
            
            -- 插入数据到MYTABLE表
            INSERT INTO MYTABLE (ID, DATE1, QUARTAL, MONTH, WEEKDAY) VALUES (TO_CHAR(CURRENT_DATE1, 'YYYY'), CURRENT_DATE1, CURRENT_QUARTER, CURRENT_MONTH, CURRENT_WEEKDAY);
          END;
        END LOOP;
      END LOOP;
    END LOOP;
  END LOOP;
END FILL_MYTABLE;
/
英文:

I have to create procedure that will fill in the table MYTABLE with dates from 2000-01-01 to 2100-01-01

CREATE TABLE MYTABLE (
ID VARCHAR2(4), 
DATE1 DATE, 
QUARTAL VARCHAR2(4), 
MONTH NUMBER, 
WEEKDAY VARCHAR2(2) 
); 

ID must be in format yyyy, DATE1 will be dates from 2000-01-01 to 2100-01-01, QUARTAL will either be Q1, Q2, Q3 or Q4, MONTH will be from 1-12, WEEKDAY will show either YES or NO.

答案1

得分: 2

这是你需要的行生成器。以下是示例。

日期格式(只是了解是什么):

SQL> alter session set nls_date_Format = 'yyyy-mm-dd';

Session altered.

CTE在指定的日期之间创建日历:

SQL> with temp (datum) as
  2    (select date '2000-01-01' + level - 1
  3     from dual
  4     connect by level <= date '2100-01-01' - date '2000-01-01' + 1
  5    )
  6  select min(datum), max(datum) from temp;

MIN(DATUM) MAX(DATUM)
---------- ----------
2000-01-01 2100-01-01

代码返回值,正如你所解释的。我只提取了一个小的子集,只是为了说明查询返回的值:

SQL> with temp (datum) as
  2    (select date '2000-01-01' + level - 1
  3     from dual
  4     connect by level <= date '2100-01-01' - date '2000-01-01' + 1
  5    )
  6  select extract(year from datum) as id,
  7    datum as date1,
  8    to_char(datum, 'q') as quartal,
  9    extract(month from datum) as month,
 10    case when to_char(datum, 'dy', 'nls_date_language = english') in ('sat', 'sun') then 'N'
 11         else 'Y'
 12    end as weekday
 13  from temp
 14  where datum between date '2000-03-25' and date '2000-04-05'
 15  order by datum;

        ID DATE1      Q      MONTH W
---------- ---------- - ---------- -
      2000 2000-03-25 1          3 N
      2000 2000-03-26 1          3 N
      2000 2000-03-27 1          3 Y
      2000 2000-03-28 1          3 Y
      2000 2000-03-29 1          3 Y
      2000 2000-03-30 1          3 Y
      2000 2000-03-31 1          3 Y
      2000 2000-04-01 2          4 N
      2000 2000-04-02 2          4 N
      2000 2000-04-03 2          4 Y
      2000 2000-04-04 2          4 Y
      2000 2000-04-05 2          4 Y

12 rows selected.

SQL>

插入到目标表的部分就留给你了。

英文:

It is row generator you need. Here's example.

Date format (just to know what is what):

SQL&gt; alter session set nls_date_Format = &#39;yyyy-mm-dd&#39;;
Session altered.

CTE creates calendar between dates you specified:

SQL&gt; with temp (datum) as
2    (select date &#39;2000-01-01&#39; + level - 1
3     from dual
4     connect by level &lt;= date &#39;2100-01-01&#39; - date &#39;2000-01-01&#39; + 1
5    )
6  select min(datum), max(datum) from temp;
MIN(DATUM) MAX(DATUM)
---------- ----------
2000-01-01 2100-01-01

Code that returns values, as you explained. I'm extracting only a small subset, just to illustrate values query returns:

SQL&gt; with temp (datum) as
2    (select date &#39;2000-01-01&#39; + level - 1
3     from dual
4     connect by level &lt;= date &#39;2100-01-01&#39; - date &#39;2000-01-01&#39; + 1
5    )
6  select extract(year from datum) as id,
7    datum as date1,
8    to_char(datum, &#39;q&#39;) as quartal,
9    extract(month from datum) as month,
10    case when to_char(datum, &#39;dy&#39;, &#39;nls_date_language = english&#39;) in (&#39;sat&#39;, &#39;sun&#39;) then &#39;N&#39;
11         else &#39;Y&#39;
12    end as weekday
13  from temp
14  where datum between date &#39;2000-03-25&#39; and date &#39;2000-04-05&#39;
15  order by datum;
ID DATE1      Q      MONTH W
---------- ---------- - ---------- -
2000 2000-03-25 1          3 N
2000 2000-03-26 1          3 N
2000 2000-03-27 1          3 Y
2000 2000-03-28 1          3 Y
2000 2000-03-29 1          3 Y
2000 2000-03-30 1          3 Y
2000 2000-03-31 1          3 Y
2000 2000-04-01 2          4 N
2000 2000-04-02 2          4 N
2000 2000-04-03 2          4 Y
2000 2000-04-04 2          4 Y
2000 2000-04-05 2          4 Y
12 rows selected.
SQL&gt;

I'll leave inserting into target table to you.

答案2

得分: 0

以下代码将创建一个完整的日历表,从你想要的任何日期开始,并生成你想要的天数。有两个占位符应该正确放置。在代码中,它们已经设置为从2000年01月01日生成日历到2099年12月31日。

--
-- 创建日历表
--
-- 如果已经存在,删除表
--
--DROP TABLE CALENDAR_TABLE;
--
CREATE TABLE CALENDAR_TABLE AS
	WITH 
		base_calendar AS
			(
				SELECT CurrDate         AS Day_ID,
				1                       AS Day_Time_Span,
				CurrDate                AS Day_End_Date,
				TO_CHAR(CurrDate,'Day') AS Week_Day_Full,
				TO_CHAR(CurrDate,'DY')  AS Week_Day_Short,
				TO_NUMBER(TRIM(leading '0' FROM TO_CHAR(CurrDate,'D')))                 AS Day_Num_of_Week,
				TO_NUMBER(TRIM(leading '0' FROM TO_CHAR(CurrDate,'DD')))                AS Day_Num_of_Month,
				TO_NUMBER(TRIM(leading '0' FROM TO_CHAR(CurrDate,'DDD')))               AS Day_Num_of_Year,
				UPPER(TO_CHAR(CurrDate,'Mon') || '-' || TO_CHAR(CurrDate,'YYYY'))      AS Month_ID,
				TO_CHAR(CurrDate,'Mon') || ' ' || TO_CHAR(CurrDate,'YYYY')             AS Month_Short_Desc,
				RTRIM(TO_CHAR(CurrDate,'Month')) || ' ' || TO_CHAR(CurrDate,'YYYY')    AS Month_Long_Desc,
				TO_CHAR(CurrDate,'Mon')    AS Month_Short,
				TO_CHAR(CurrDate,'Month')  AS Month_Long,
				TO_NUMBER(TRIM(leading '0' FROM TO_CHAR(CurrDate,'MM')))                AS Month_Num_of_Year,
				'Q' || UPPER(TO_CHAR(CurrDate,'Q') || '-' || TO_CHAR(CurrDate,'YYYY')) AS Quarter_ID,
				TO_NUMBER(TO_CHAR(CurrDate,'Q'))                                       AS Quarter_Num_of_Year,
				CASE
				  WHEN TO_NUMBER(TO_CHAR(CurrDate,'Q')) <= 2
				  THEN 1
				  ELSE 2
				END                                                                      AS half_num_of_year,
				CASE
				  WHEN TO_NUMBER(TO_CHAR(CurrDate,'Q')) <= 2
				  THEN 'H'
					|| 1
					|| '-'
					|| TO_CHAR(CurrDate,'YYYY')
				  ELSE 'H'
					|| 2
					|| '-'
					|| TO_CHAR(CurrDate,'YYYY')
				END                                                                      AS half_of_year_id,
				TO_CHAR(CurrDate,'YYYY')                                               AS Year_ID
			  FROM
				(
					SELECT level n,
						-- 日历从下一行中日期的后一天开始
						TO_DATE('31/12/1999','DD/MM/YYYY') + NUMTODSINTERVAL(level,'DAY') CurrDate
					FROM dual
						-- 要添加到表中的天数在下一行中
					CONNECT BY level <= 36525
				)
			)
SELECT  day_id,
        day_time_span,
        day_end_date,
        week_day_full,
        week_day_short,
        day_num_of_week,
        day_num_of_month,
        day_num_of_year,
        month_id,
        COUNT(*) OVER (PARTITION BY month_id)    AS Month_Time_Span,
        MAX(day_id) OVER (PARTITION BY month_id) AS Month_End_Date,
        month_short_desc,
        month_long_desc,
        month_short,
        month_long,
        month_num_of_year,
        quarter_id,
        COUNT(*) OVER (PARTITION BY quarter_id)    AS Quarter_Time_Span,
        MAX(day_id) OVER (PARTITION BY quarter_id) AS Quarter_End_Date,
        quarter_num_of_year,
        half_num_of_year,
        half_of_year_id,
        COUNT(*) OVER (PARTITION BY half_of_year_id)    AS Half_Year_Time_Span,
        MAX(day_id) OVER (PARTITION BY half_of_year_id) AS Half_Year_End_Date,
        year_id,
        COUNT(*) OVER (PARTITION BY year_id)    AS Year_Time_Span,
        MAX(day_id) OVER (PARTITION BY year_id) AS Year_End_Date
FROM base_calendar
ORDER BY day_id

在创建表之后进行测试

Select Min(DAY_ID) "START_DATE", Max(DAY_ID) "END_DATE", Count(DAY_ID) "NUM_OF_DATES" 
From Calendar_Table

START_DATE END_DATE  NUM_OF_DATES
---------- --------- ------------
01-JAN-00  31-DEC-99        36525
英文:

The code below will create full calendar table starting any day you want and generating as many days you want. There are 2 placeholders that should be put correctly. In the code they are allready set to generate calendar from 01.01.2000 until 31.12.2099

--
-- Create calendar table
--
-- Drop table if it alreadyy exist
--
--DROP TABLE CALENDAR_TABLE;
--
CREATE TABLE CALENDAR_TABLE AS
	WITH 
		base_calendar AS
			(
				SELECT CurrDate         AS Day_ID,
				1                       AS Day_Time_Span,
				CurrDate                AS Day_End_Date,
				TO_CHAR(CurrDate,&#39;Day&#39;) AS Week_Day_Full,
				TO_CHAR(CurrDate,&#39;DY&#39;)  AS Week_Day_Short,
				TO_NUMBER(TRIM(leading &#39;0&#39; FROM TO_CHAR(CurrDate,&#39;D&#39;))) 				AS Day_Num_of_Week,
				TO_NUMBER(TRIM(leading &#39;0&#39; FROM TO_CHAR(CurrDate,&#39;DD&#39;))) 				AS Day_Num_of_Month,
				TO_NUMBER(TRIM(leading &#39;0&#39; FROM TO_CHAR(CurrDate,&#39;DDD&#39;))) 				AS Day_Num_of_Year,
				UPPER(TO_CHAR(CurrDate,&#39;Mon&#39;) || &#39;-&#39; || TO_CHAR(CurrDate,&#39;YYYY&#39;)) 		AS Month_ID,
				TO_CHAR(CurrDate,&#39;Mon&#39;) || &#39; &#39; || TO_CHAR(CurrDate,&#39;YYYY&#39;) 				AS Month_Short_Desc,
				RTRIM(TO_CHAR(CurrDate,&#39;Month&#39;)) || &#39; &#39; || TO_CHAR(CurrDate,&#39;YYYY&#39;) 	AS Month_Long_Desc,
				TO_CHAR(CurrDate,&#39;Mon&#39;)    AS Month_Short,
				TO_CHAR(CurrDate,&#39;Month&#39;)  AS Month_Long,
				TO_NUMBER(TRIM(leading &#39;0&#39; FROM TO_CHAR(CurrDate,&#39;MM&#39;))) 	AS Month_Num_of_Year,
				&#39;Q&#39; || UPPER(TO_CHAR(CurrDate,&#39;Q&#39;) || &#39;-&#39; || TO_CHAR(CurrDate,&#39;YYYY&#39;))  AS Quarter_ID,
				TO_NUMBER(TO_CHAR(CurrDate,&#39;Q&#39;)) 	AS Quarter_Num_of_Year,
				CASE
				  WHEN TO_NUMBER(TO_CHAR(CurrDate,&#39;Q&#39;)) &lt;= 2
				  THEN 1
				  ELSE 2
				END 						AS half_num_of_year,
				CASE
				  WHEN TO_NUMBER(TO_CHAR(CurrDate,&#39;Q&#39;)) &lt;= 2
				  THEN &#39;H&#39;
					|| 1
					|| &#39;-&#39;
					|| TO_CHAR(CurrDate,&#39;YYYY&#39;)
				  ELSE &#39;H&#39;
					|| 2
					|| &#39;-&#39;
					|| TO_CHAR(CurrDate,&#39;YYYY&#39;)
				END                      AS half_of_year_id,
				TO_CHAR(CurrDate,&#39;YYYY&#39;) AS Year_ID
			  FROM
				(
					SELECT level n,
						-- Calendar starts at the day after the date in next line
						TO_DATE(&#39;31/12/1999&#39;,&#39;DD/MM/YYYY&#39;) + NUMTODSINTERVAL(level,&#39;DAY&#39;) CurrDate
					FROM dual
						-- Tthe number of days to be added to the table in next line
					CONNECT BY level &lt;= 36525
				)
			)
SELECT	day_id,
		day_time_span,
		day_end_date,
		week_day_full,
		week_day_short,
		day_num_of_week,
		day_num_of_month,
		day_num_of_year,
		month_id,
		COUNT(*) OVER (PARTITION BY month_id)    AS Month_Time_Span,
		MAX(day_id) OVER (PARTITION BY month_id) AS Month_End_Date,
		month_short_desc,
		month_long_desc,
		month_short,
		month_long,
		month_num_of_year,
		quarter_id,
		COUNT(*) OVER (PARTITION BY quarter_id)    AS Quarter_Time_Span,
		MAX(day_id) OVER (PARTITION BY quarter_id) AS Quarter_End_Date,
		quarter_num_of_year,
		half_num_of_year,
		half_of_year_id,
		COUNT(*) OVER (PARTITION BY half_of_year_id)    AS Half_Year_Time_Span,
		MAX(day_id) OVER (PARTITION BY half_of_year_id) AS Half_Year_End_Date,
		year_id,
		COUNT(*) OVER (PARTITION BY year_id)    AS Year_Time_Span,
		MAX(day_id) OVER (PARTITION BY year_id) AS Year_End_Date
FROM base_calendar
ORDER BY day_id

Test after the table is created

Select Min(DAY_ID) &quot;START_DATE&quot;, Max(DAY_ID) &quot;END_DATE&quot;, Count(DAY_ID) &quot;NUM_OF_DATES&quot; 
From Calendar_Table

START_DATE END_DATE  NUM_OF_DATES
---------- --------- ------------
01-JAN-00  31-DEC-99        36525

huangapple
  • 本文由 发表于 2023年3月12日 16:30:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75711902.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定