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

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

Inserting date with procedure in oracle PL/SQL

问题

  1. -- 创建存储过程,向MYTABLE表插入日期数据
  2. CREATE OR REPLACE PROCEDURE FILL_MYTABLE AS
  3. BEGIN
  4. FOR YEAR_IN_NUMBER IN 2000..2100 LOOP
  5. FOR MONTH_IN_NUMBER IN 1..12 LOOP
  6. FOR QUARTER_IN_NUMBER IN 1..4 LOOP
  7. FOR DAY_IN_NUMBER IN 1..31 LOOP
  8. -- 计算日期
  9. DECLARE
  10. CURRENT_DATE1 DATE;
  11. CURRENT_QUARTER VARCHAR2(4);
  12. CURRENT_MONTH NUMBER;
  13. CURRENT_WEEKDAY VARCHAR2(2);
  14. BEGIN
  15. CURRENT_DATE1 := TO_DATE(YEAR_IN_NUMBER || '-' || LPAD(MONTH_IN_NUMBER, 2, '0') || '-' || LPAD(DAY_IN_NUMBER, 2, '0'), 'YYYY-MM-DD');
  16. CURRENT_QUARTER := 'Q' || QUARTER_IN_NUMBER;
  17. CURRENT_MONTH := MONTH_IN_NUMBER;
  18. -- 计算星期几
  19. CURRENT_WEEKDAY := CASE WHEN TO_CHAR(CURRENT_DATE1, 'D') BETWEEN 2 AND 6 THEN 'YES' ELSE 'NO' END;
  20. -- 插入数据到MYTABLE
  21. INSERT INTO MYTABLE (ID, DATE1, QUARTAL, MONTH, WEEKDAY) VALUES (TO_CHAR(CURRENT_DATE1, 'YYYY'), CURRENT_DATE1, CURRENT_QUARTER, CURRENT_MONTH, CURRENT_WEEKDAY);
  22. END;
  23. END LOOP;
  24. END LOOP;
  25. END LOOP;
  26. END LOOP;
  27. END FILL_MYTABLE;
  28. /
英文:

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

  1. CREATE TABLE MYTABLE (
  2. ID VARCHAR2(4),
  3. DATE1 DATE,
  4. QUARTAL VARCHAR2(4),
  5. MONTH NUMBER,
  6. WEEKDAY VARCHAR2(2)
  7. );

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

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

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

  1. SQL> alter session set nls_date_Format = 'yyyy-mm-dd';
  2. Session altered.

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

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

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

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

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

英文:

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

Date format (just to know what is what):

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

CTE creates calendar between dates you specified:

  1. SQL&gt; with temp (datum) as
  2. 2 (select date &#39;2000-01-01&#39; + level - 1
  3. 3 from dual
  4. 4 connect by level &lt;= date &#39;2100-01-01&#39; - date &#39;2000-01-01&#39; + 1
  5. 5 )
  6. 6 select min(datum), max(datum) from temp;
  7. MIN(DATUM) MAX(DATUM)
  8. ---------- ----------
  9. 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:

  1. SQL&gt; with temp (datum) as
  2. 2 (select date &#39;2000-01-01&#39; + level - 1
  3. 3 from dual
  4. 4 connect by level &lt;= date &#39;2100-01-01&#39; - date &#39;2000-01-01&#39; + 1
  5. 5 )
  6. 6 select extract(year from datum) as id,
  7. 7 datum as date1,
  8. 8 to_char(datum, &#39;q&#39;) as quartal,
  9. 9 extract(month from datum) as month,
  10. 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. 11 else &#39;Y&#39;
  12. 12 end as weekday
  13. 13 from temp
  14. 14 where datum between date &#39;2000-03-25&#39; and date &#39;2000-04-05&#39;
  15. 15 order by datum;
  16. ID DATE1 Q MONTH W
  17. ---------- ---------- - ---------- -
  18. 2000 2000-03-25 1 3 N
  19. 2000 2000-03-26 1 3 N
  20. 2000 2000-03-27 1 3 Y
  21. 2000 2000-03-28 1 3 Y
  22. 2000 2000-03-29 1 3 Y
  23. 2000 2000-03-30 1 3 Y
  24. 2000 2000-03-31 1 3 Y
  25. 2000 2000-04-01 2 4 N
  26. 2000 2000-04-02 2 4 N
  27. 2000 2000-04-03 2 4 Y
  28. 2000 2000-04-04 2 4 Y
  29. 2000 2000-04-05 2 4 Y
  30. 12 rows selected.
  31. SQL&gt;

I'll leave inserting into target table to you.

答案2

得分: 0

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

  1. --
  2. -- 创建日历表
  3. --
  4. -- 如果已经存在,删除表
  5. --
  6. --DROP TABLE CALENDAR_TABLE;
  7. --
  8. CREATE TABLE CALENDAR_TABLE AS
  9. WITH
  10. base_calendar AS
  11. (
  12. SELECT CurrDate AS Day_ID,
  13. 1 AS Day_Time_Span,
  14. CurrDate AS Day_End_Date,
  15. TO_CHAR(CurrDate,'Day') AS Week_Day_Full,
  16. TO_CHAR(CurrDate,'DY') AS Week_Day_Short,
  17. TO_NUMBER(TRIM(leading '0' FROM TO_CHAR(CurrDate,'D'))) AS Day_Num_of_Week,
  18. TO_NUMBER(TRIM(leading '0' FROM TO_CHAR(CurrDate,'DD'))) AS Day_Num_of_Month,
  19. TO_NUMBER(TRIM(leading '0' FROM TO_CHAR(CurrDate,'DDD'))) AS Day_Num_of_Year,
  20. UPPER(TO_CHAR(CurrDate,'Mon') || '-' || TO_CHAR(CurrDate,'YYYY')) AS Month_ID,
  21. TO_CHAR(CurrDate,'Mon') || ' ' || TO_CHAR(CurrDate,'YYYY') AS Month_Short_Desc,
  22. RTRIM(TO_CHAR(CurrDate,'Month')) || ' ' || TO_CHAR(CurrDate,'YYYY') AS Month_Long_Desc,
  23. TO_CHAR(CurrDate,'Mon') AS Month_Short,
  24. TO_CHAR(CurrDate,'Month') AS Month_Long,
  25. TO_NUMBER(TRIM(leading '0' FROM TO_CHAR(CurrDate,'MM'))) AS Month_Num_of_Year,
  26. 'Q' || UPPER(TO_CHAR(CurrDate,'Q') || '-' || TO_CHAR(CurrDate,'YYYY')) AS Quarter_ID,
  27. TO_NUMBER(TO_CHAR(CurrDate,'Q')) AS Quarter_Num_of_Year,
  28. CASE
  29. WHEN TO_NUMBER(TO_CHAR(CurrDate,'Q')) <= 2
  30. THEN 1
  31. ELSE 2
  32. END AS half_num_of_year,
  33. CASE
  34. WHEN TO_NUMBER(TO_CHAR(CurrDate,'Q')) <= 2
  35. THEN 'H'
  36. || 1
  37. || '-'
  38. || TO_CHAR(CurrDate,'YYYY')
  39. ELSE 'H'
  40. || 2
  41. || '-'
  42. || TO_CHAR(CurrDate,'YYYY')
  43. END AS half_of_year_id,
  44. TO_CHAR(CurrDate,'YYYY') AS Year_ID
  45. FROM
  46. (
  47. SELECT level n,
  48. -- 日历从下一行中日期的后一天开始
  49. TO_DATE('31/12/1999','DD/MM/YYYY') + NUMTODSINTERVAL(level,'DAY') CurrDate
  50. FROM dual
  51. -- 要添加到表中的天数在下一行中
  52. CONNECT BY level <= 36525
  53. )
  54. )
  55. SELECT day_id,
  56. day_time_span,
  57. day_end_date,
  58. week_day_full,
  59. week_day_short,
  60. day_num_of_week,
  61. day_num_of_month,
  62. day_num_of_year,
  63. month_id,
  64. COUNT(*) OVER (PARTITION BY month_id) AS Month_Time_Span,
  65. MAX(day_id) OVER (PARTITION BY month_id) AS Month_End_Date,
  66. month_short_desc,
  67. month_long_desc,
  68. month_short,
  69. month_long,
  70. month_num_of_year,
  71. quarter_id,
  72. COUNT(*) OVER (PARTITION BY quarter_id) AS Quarter_Time_Span,
  73. MAX(day_id) OVER (PARTITION BY quarter_id) AS Quarter_End_Date,
  74. quarter_num_of_year,
  75. half_num_of_year,
  76. half_of_year_id,
  77. COUNT(*) OVER (PARTITION BY half_of_year_id) AS Half_Year_Time_Span,
  78. MAX(day_id) OVER (PARTITION BY half_of_year_id) AS Half_Year_End_Date,
  79. year_id,
  80. COUNT(*) OVER (PARTITION BY year_id) AS Year_Time_Span,
  81. MAX(day_id) OVER (PARTITION BY year_id) AS Year_End_Date
  82. FROM base_calendar
  83. ORDER BY day_id

在创建表之后进行测试

  1. Select Min(DAY_ID) "START_DATE", Max(DAY_ID) "END_DATE", Count(DAY_ID) "NUM_OF_DATES"
  2. From Calendar_Table
  3. START_DATE END_DATE NUM_OF_DATES
  4. ---------- --------- ------------
  5. 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

  1. --
  2. -- Create calendar table
  3. --
  4. -- Drop table if it alreadyy exist
  5. --
  6. --DROP TABLE CALENDAR_TABLE;
  7. --
  8. CREATE TABLE CALENDAR_TABLE AS
  9. WITH
  10. base_calendar AS
  11. (
  12. SELECT CurrDate AS Day_ID,
  13. 1 AS Day_Time_Span,
  14. CurrDate AS Day_End_Date,
  15. TO_CHAR(CurrDate,&#39;Day&#39;) AS Week_Day_Full,
  16. TO_CHAR(CurrDate,&#39;DY&#39;) AS Week_Day_Short,
  17. TO_NUMBER(TRIM(leading &#39;0&#39; FROM TO_CHAR(CurrDate,&#39;D&#39;))) AS Day_Num_of_Week,
  18. TO_NUMBER(TRIM(leading &#39;0&#39; FROM TO_CHAR(CurrDate,&#39;DD&#39;))) AS Day_Num_of_Month,
  19. TO_NUMBER(TRIM(leading &#39;0&#39; FROM TO_CHAR(CurrDate,&#39;DDD&#39;))) AS Day_Num_of_Year,
  20. UPPER(TO_CHAR(CurrDate,&#39;Mon&#39;) || &#39;-&#39; || TO_CHAR(CurrDate,&#39;YYYY&#39;)) AS Month_ID,
  21. TO_CHAR(CurrDate,&#39;Mon&#39;) || &#39; &#39; || TO_CHAR(CurrDate,&#39;YYYY&#39;) AS Month_Short_Desc,
  22. RTRIM(TO_CHAR(CurrDate,&#39;Month&#39;)) || &#39; &#39; || TO_CHAR(CurrDate,&#39;YYYY&#39;) AS Month_Long_Desc,
  23. TO_CHAR(CurrDate,&#39;Mon&#39;) AS Month_Short,
  24. TO_CHAR(CurrDate,&#39;Month&#39;) AS Month_Long,
  25. TO_NUMBER(TRIM(leading &#39;0&#39; FROM TO_CHAR(CurrDate,&#39;MM&#39;))) AS Month_Num_of_Year,
  26. &#39;Q&#39; || UPPER(TO_CHAR(CurrDate,&#39;Q&#39;) || &#39;-&#39; || TO_CHAR(CurrDate,&#39;YYYY&#39;)) AS Quarter_ID,
  27. TO_NUMBER(TO_CHAR(CurrDate,&#39;Q&#39;)) AS Quarter_Num_of_Year,
  28. CASE
  29. WHEN TO_NUMBER(TO_CHAR(CurrDate,&#39;Q&#39;)) &lt;= 2
  30. THEN 1
  31. ELSE 2
  32. END AS half_num_of_year,
  33. CASE
  34. WHEN TO_NUMBER(TO_CHAR(CurrDate,&#39;Q&#39;)) &lt;= 2
  35. THEN &#39;H&#39;
  36. || 1
  37. || &#39;-&#39;
  38. || TO_CHAR(CurrDate,&#39;YYYY&#39;)
  39. ELSE &#39;H&#39;
  40. || 2
  41. || &#39;-&#39;
  42. || TO_CHAR(CurrDate,&#39;YYYY&#39;)
  43. END AS half_of_year_id,
  44. TO_CHAR(CurrDate,&#39;YYYY&#39;) AS Year_ID
  45. FROM
  46. (
  47. SELECT level n,
  48. -- Calendar starts at the day after the date in next line
  49. TO_DATE(&#39;31/12/1999&#39;,&#39;DD/MM/YYYY&#39;) + NUMTODSINTERVAL(level,&#39;DAY&#39;) CurrDate
  50. FROM dual
  51. -- Tthe number of days to be added to the table in next line
  52. CONNECT BY level &lt;= 36525
  53. )
  54. )
  55. SELECT day_id,
  56. day_time_span,
  57. day_end_date,
  58. week_day_full,
  59. week_day_short,
  60. day_num_of_week,
  61. day_num_of_month,
  62. day_num_of_year,
  63. month_id,
  64. COUNT(*) OVER (PARTITION BY month_id) AS Month_Time_Span,
  65. MAX(day_id) OVER (PARTITION BY month_id) AS Month_End_Date,
  66. month_short_desc,
  67. month_long_desc,
  68. month_short,
  69. month_long,
  70. month_num_of_year,
  71. quarter_id,
  72. COUNT(*) OVER (PARTITION BY quarter_id) AS Quarter_Time_Span,
  73. MAX(day_id) OVER (PARTITION BY quarter_id) AS Quarter_End_Date,
  74. quarter_num_of_year,
  75. half_num_of_year,
  76. half_of_year_id,
  77. COUNT(*) OVER (PARTITION BY half_of_year_id) AS Half_Year_Time_Span,
  78. MAX(day_id) OVER (PARTITION BY half_of_year_id) AS Half_Year_End_Date,
  79. year_id,
  80. COUNT(*) OVER (PARTITION BY year_id) AS Year_Time_Span,
  81. MAX(day_id) OVER (PARTITION BY year_id) AS Year_End_Date
  82. FROM base_calendar
  83. ORDER BY day_id

Test after the table is created

  1. Select Min(DAY_ID) &quot;START_DATE&quot;, Max(DAY_ID) &quot;END_DATE&quot;, Count(DAY_ID) &quot;NUM_OF_DATES&quot;
  2. From Calendar_Table
  3. START_DATE END_DATE NUM_OF_DATES
  4. ---------- --------- ------------
  5. 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:

确定