我是plsql的新手,并且在我的任务中遇到了一些麻烦。我被要求创建一个日期维度表并用各种日期信息填充它。
我按如下方式创建了我的表
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;
然后我得到错误,表明调用函数是错误的参数类型。我想知道是否有人可以帮忙解决这个问题,并告诉我哪里出错了。干杯
答案 0 :(得分:1)
首先,你有程序获得
v_first_date_in DATE,
v_second_date_in DATE
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;
但请注意:如果此处的日期类型为(&#39; dd / mm / yyyy&#39;),则您在此过程中的处理日期(&#39; ddmmyyyy&#39;)不正确。< / p>
希望它会有所帮助!
答案 1 :(得分:0)
如果您真的不需要任何日期格式化和解析,请始终使用SQL标准DATE
literal:
BEGIN
sp_populate_dates(DATE '2005-01-01', DATE '2006-01-01');
END;
答案 2 :(得分:0)
您可以使用以下查询填充此类表格(针对2000年至2030年之间的日期):
CREATE TABLE DIM_DATE
as
(
select
TO_NUMBER(TO_CHAR(DATE_D,'j')) as DATE_J,
DATE_D,
TO_CHAR(DATE_D,'YYYY-MM-DD') as DATE_V,
TO_NUMBER(TO_CHAR(DATE_D,'YYYY')) as YEAR_NUM,
TO_NUMBER(TO_CHAR(DATE_D,'Q')) as QUARTER_NUM,
TO_NUMBER(TO_CHAR(DATE_D,'MM')) as MONTH_NUM,
TRIM(TO_CHAR(DATE_D,'Month','nls_date_language=english')) as MONTH_DESC,
TO_NUMBER(TO_CHAR(DATE_D,'IW')) as ISO_WEEK_NUM,
TO_NUMBER(TO_CHAR(DATE_D,'IYYY')) as ISO_YEAR_NUM,
TO_NUMBER(TO_CHAR(DATE_D,'DD')) as DAY_OF_MONTH_NUM,
TO_NUMBER(TO_CHAR(DATE_D,'D')) as DAY_OF_WEEK_NUM,
TRIM(TO_CHAR(DATE_D,'Day','nls_date_language=english')) as DAY_OF_WEEK_DESC,
(CASE WHEN TRIM(TO_CHAR(DATE_D,'Day','nls_date_language=english')) IN ('Saturday','Sunday') THEN 'Weekend' ELSE 'Weekday' END) as DAY_TYPE_DESC
from
(
select
to_date('1999-12-31','YYYY-MM-DD')+ROWNUM as DATE_D
from
dual
connect by level <= to_date('2029-12-31','YYYY-MM-DD')-to_date('1999-12-31','YYYY-MM-DD')
)
);