2015-11-08 61 views
0

我对plsql非常陌生,在分配任务时遇到了一些麻烦。我被要求创建一个日期维度表并用各种日期信息填充它。在PL/SQL中的两个日期范围之间填充日期维度

我创造了我的表如下

CREATE TABLE date_dimension_table 
( 
v_date DATE NOT NULL, 
full_date VARCHAR2(50) NOT NULL, 
day_of_week NUMBER(1,0) NOT NULL, 
day_in_month NUMBER(2,0) NOT NULL, 
day_in_year NUMBER(3,0) NOT NULL, 
last_day_of_week_flag VARCHAR2(1) NOT NULL, 
last_day_of_month_flag VARCHAR2(1) NOT NULL, 
end_of_week_date DATE NOT NULL, 
month_number NUMBER(2,0) NOT NULL, 
month_name VARCHAR2(32) NOT NULL, 
year_month CHAR(32) NOT NULL, 
quarter_number NUMBER(1,0) NOT NULL, 
year_and_quarter VARCHAR2(32) NOT NULL, 
v_year NUMBER(4,0) NOT NULL, 
CONSTRAINT date_dimension_table_PK PRIMARY KEY (v_date) 
); 

我然后创建以下程序来填充表。

create or replace PROCEDURE sp_populate_dates(
v_first_date_in DATE, 
v_second_date_in DATE) 

AS 
--Declare two variables as DATE datatypes 
v_current_date DATE; 
v_end_date  DATE; 

BEGIN 

--Assign the start date and end date to the variables 
v_current_date := TO_DATE(v_first_date_in, 'DDMMYYYY'); 
v_end_date := TO_DATE(v_second_date_in, 'DDMMYYYY'); 


--Delete whats currently in the table 
DELETE FROM date_dimension_table; 

--condition checks if the first date is before the second date 
WHILE v_current_date <= v_end_date 
LOOP 
--insert into table 
INSERT INTO date_dimension_table 
(
    v_date, 
    full_date, 
    day_of_week, 
    day_in_month, 
    day_in_year, 
    last_day_of_week_flag, 
    last_day_of_month_flag, 
    end_of_week_date, 
    month_number, 
    month_name, 
    year_month, 
    quarter_number, 
    year_and_quarter, 
    v_year  
)  
VALUES 
(
    v_current_date,         --date 
    TO_CHAR(v_current_date, 'Day, Month DD, YYYY'), --full date 
    TO_NUMBER(TO_CHAR(v_current_date, 'D')) -1,  --day in week 
    TO_CHAR(v_current_date,'DD'),     --day in month   
    TO_CHAR(v_current_date,'DDD'),     --day in year 
    CASE           --last day of week flag 
     WHEN TO_CHAR(v_current_date,'FMDay') = 'Sunday' THEN 'Y' 
     ELSE 'N' 
    END, 
    CASE           --last day of month flag 
     WHEN last_day(TO_DATE(v_current_date, 'MM/DD/YYYY')) = TO_DATE(v_current_date, 'MM/DD/YYYY') THEN 'Y' 
     ELSE 'N' 
    END, 
    CASE           --date of next sunday 
     WHEN TO_CHAR(v_current_date,'FMDay') = 'Sunday' THEN v_current_date 
     ELSE NEXT_DAY(v_current_date,'SUNDAY') 
    END, 
    TO_CHAR(v_current_date,'MM'),     --month number 
    TO_CHAR(v_current_date,'MONTH'),    --name of month 
    TO_CHAR(v_current_date,'MONTH YYYY'),   --month and year   
    TO_CHAR(v_current_date,'Q'),     --number of quarter 
    TO_CHAR(v_current_date,'YYYY Q'),    --year and quarter 
    TO_CHAR(v_current_date,'YYYY')     --year  

); 
--Increment and assign the current date value to be re-evaluated 
v_current_date := v_current_date + 1; 

END LOOP; 
END; 

由于程序具有插入来自日期范围信息,我用两个日期作为输入参数并且它投掷错误。

例子:

BEGIN 
sp_populate_dates(01/01/2005, 01/01/2006); 
END; 

我当时收到错误提示这是错误的类型参数的函数调用。我想知道是否有人可以帮助这个请,并告诉我我要去哪里错了。干杯

回答

1

首先,你必须的过程,得到

v_first_date_in DATE, 
v_second_date_in DATE 

日期,但是你要通过甚至不是一个字符串。尝试这样的事情

BEGIN 
sp_populate_dates(TO_DATE('01/01/2005', 'dd/mm/yyyy'), TO_DATE('01/01/2005', 'dd/mm/yyyy')); 
END; 

另一件事是 - 你在程序中处理这些参数,所以你可能想通过VARCHAR2类型的变量。这意味着,

create or replace PROCEDURE sp_populate_dates(
v_first_date_in IN VARCHAR2, 
v_second_date_in IN VARCHAR2) 
... 

,并调用它像

BEGIN 
sp_populate_dates('01/01/2005','01/01/2005'); 
END; 

但是这里要小心:如果日期这里的类型是( 'DD/MM/YYYY')的过程中,你的处理日期(” ddmmyyyy')是不正确的。

希望它会帮助!

0

如果你真的不需要任何的日期格式和分析,始终使用SQL标准DATE literal

BEGIN 
    sp_populate_dates(DATE '2005-01-01', DATE '2006-01-01'); 
END; 
相关问题