我正在为某些维度编写一些 DDL/PLSQL,这样我就可以方便地将它作为备份,并且我正在使用过程/函数来自动化一切。对于我的问题,我关注的是日期维度。我遇到的问题是,当我尝试从另一个存储过程运行一个存储过程时,我收到一组错误消息,这些消息说,
- [ORA-04068] 包的现有状态已被丢弃,未执行、更改或删除存储过程
- [ORA-04065] 未执行、更改或删除存储过程“ADMIN.NEW_DATE”
- [ORA-06508] PL/SQLL 找不到被调用的程序单元:“ADMIN.NEW_DATE”
- [ORA-06512] 在“ADMIN.DATE_DIM_CREATE,第 85 行
- [ORA-06512] 在第 2 行
我还应该指出,其中一个存储过程调用了一组函数来处理将插入日期维度表中的日期维度值。
这是第一个存储过程 DATE_DIM_CREATE 的代码,它调用 NEW_DATE:
create or replace
PROCEDURE DATE_DIM_CREATE
AUTHID CURRENT_USER
IS
V_START_DATE DATE := TO_DATE('01/01/1900','MM/DD/YYYY');
V_CURRENT_DATE DATE := V_START_DATE;
V_END_DATE DATE := TO_DATE('12/31/2099','MM/DD/YYYY');
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE "DATE_DIM" PURGE';
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_LANGUAGE = ''AMERICAN'' ';
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_TERRITORY = ''AMERICA'' ';
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = ''GREGORIAN'' ';
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_FORMAT = ''MM/DD/YYYY'' ';
EXECUTE IMMEDIATE
'CREATE TABLE DATE_DIM
(
DATE_KEY NUMBER(8, 0) NOT NULL,
DATE_TYPE VARCHAR2(14),
FULL_DATE DATE,
FULL_DATE_REVERSE VARCHAR2(10),
FULL_DATE_DESCRIPTION VARCHAR2(31),
DAY_NUMBER NUMBER(2, 0),
DAY_NAME VARCHAR2(9),
DAY_SHORT VARCHAR2(3),
FIRST_DAY_IN_MONTH DATE,
LAST_DAY_IN_MONTH DATE,
FIRST_DAY_IN_PREVIOUS_MONTH DATE,
LAST_DAY_IN_PREVIOUS_MONTH DATE,
FIRST_DAY_IN_NEXT_MONTH DATE,
LAST_DAY_IN_NEXT_MONTH DATE,
FIRST_DAY_IN_CALENDAR_QTR DATE,
LAST_DAY_IN_CALENDAR_QTR DATE,
FIRST_DAY_IN_PREV_CALENDAR_QTR DATE,
LAST_DAY_IN_PREV_CALENDAR_QTR DATE,
FIRST_DAY_IN_NEXT_CALENDAR_QTR DATE,
LAST_DAY_IN_NEXT_CALENDAR_QTR DATE,
FIRST_DAY_IN_CALENDAR_YEAR DATE,
LAST_DAY_IN_CALENDAR_YEAR DATE,
DAY_NUMBER_IN_CALENDAR_YEAR NUMBER(3, 0),
FIRST_DAY_IN_FISCAL_QTR DATE,
LAST_DAY_IN_FISCAL_QTR DATE,
FIRST_DAY_IN_PREV_FISCAL_QTR DATE,
LAST_DAY_IN_PREV_FISCAL_QTR DATE,
FIRST_DAY_IN_NEXT_FISCAL_QTR DATE,
LAST_DAY_IN_NEXT_FISCAL_QTR DATE,
FIRST_DAY_IN_FISCAL_YEAR DATE,
LAST_DAY_IN_FISCAL_YEAR DATE,
DAY_NUMBER_IN_FISCAL_YEAR NUMBER(3, 0),
IS_WEEKDAY VARCHAR2(1),
IS_WEEKEND VARCHAR2(1),
WEEK_IN_MONTH NUMBER(1, 0),
WEEK_IN_CALENDAR_YEAR_ISO NUMBER(2, 0),
WEEK_IN_FISCAL_YEAR_ISO NUMBER(2, 0),
BEGIN_FULL_WEEK DATE,
END_FULL_WEEK DATE,
BEGIN_WORK_WEEK DATE,
END_WORK_WEEK DATE,
MONTH_NUMBER NUMBER(2, 0),
MONTH_NAME VARCHAR(9),
MONTH_SHORT VARCHAR(3),
CALENDAR_QUARTER NUMBER(1, 0),
CALENDAR_QUARTER_NAME VARCHAR2(11),
CALENDAR_QUARTER_YEAR VARCHAR2(9),
FISCAL_QUARTER NUMBER(1, 0),
FISCAL_QUARTER_NAME VARCHAR2(11),
FISCAL_QUARTER_YEAR VARCHAR2(9),
CALENDAR_YEAR_NUMBER NUMBER(4, 0),
CALENDAR_YEAR VARCHAR2(6),
FISCAL_YEAR_NUMBER NUMBER(4, 0),
FISCAL_YEAR VARCHAR2(6),
IS_HOLIDAY VARCHAR2(1),
IS_BUSINESS_DAY VARCHAR2(1),
CONSTRAINT DATE_KEY_PK PRIMARY KEY (DATE_KEY)
)';
EXECUTE IMMEDIATE
'COMMENT ON TABLE DATE_DIM
IS ''Date dimension table used for storing date attributes.'' ';
EXECUTE IMMEDIATE
'COMMENT ON COLUMN DATE_DIM.DATE_KEY
IS ''Date key is the primary/surrogate key for the date dimension table.'' ';
WHILE V_CURRENT_DATE <= V_END_DATE LOOP
NEW_DATE(V_CURRENT_DATE);
V_CURRENT_DATE := V_CURRENT_DATE + INTERVAL '1' DAY;
END LOOP;
NEW_DATE(TO_DATE('12/29/9999', 'MM/DD/YYYY'));
NEW_DATE(TO_DATE('12/30/9999', 'MM/DD/YYYY'));
NEW_DATE(TO_DATE('12/31/9999', 'MM/DD/YYYY'));
END DATE_DIM_CREATE;
这是 NEW_DATE 过程,它将值插入到表中并调用所有函数:
create or replace
PROCEDURE NEW_DATE(P_DATE IN DATE)
AUTHID CURRENT_USER
IS
BEGIN
INSERT INTO DATE_DIM
(
DATE_KEY,
DATE_TYPE,
FULL_DATE,
FULL_DATE_REVERSE,
FULL_DATE_DESCRIPTION,
DAY_NUMBER,
DAY_NAME,
DAY_SHORT,
FIRST_DAY_IN_MONTH,
LAST_DAY_IN_MONTH,
FIRST_DAY_IN_PREVIOUS_MONTH,
LAST_DAY_IN_PREVIOUS_MONTH,
FIRST_DAY_IN_NEXT_MONTH,
LAST_DAY_IN_NEXT_MONTH,
FIRST_DAY_IN_CALENDAR_QTR,
LAST_DAY_IN_CALENDAR_QTR,
FIRST_DAY_IN_PREV_CALENDAR_QTR,
LAST_DAY_IN_PREV_CALENDAR_QTR,
FIRST_DAY_IN_NEXT_CALENDAR_QTR,
LAST_DAY_IN_NEXT_CALENDAR_QTR,
FIRST_DAY_IN_CALENDAR_YEAR,
LAST_DAY_IN_CALENDAR_YEAR,
DAY_NUMBER_IN_CALENDAR_YEAR,
FIRST_DAY_IN_FISCAL_QTR,
LAST_DAY_IN_FISCAL_QTR,
FIRST_DAY_IN_PREV_FISCAL_QTR,
LAST_DAY_IN_PREV_FISCAL_QTR,
FIRST_DAY_IN_NEXT_FISCAL_QTR,
LAST_DAY_IN_NEXT_FISCAL_QTR,
FIRST_DAY_IN_FISCAL_YEAR,
LAST_DAY_IN_FISCAL_YEAR,
DAY_NUMBER_IN_FISCAL_YEAR,
IS_WEEKDAY,
IS_WEEKEND,
WEEK_IN_MONTH,
WEEK_IN_CALENDAR_YEAR_ISO,
WEEK_IN_FISCAL_YEAR_ISO,
BEGIN_FULL_WEEK,
END_FULL_WEEK,
BEGIN_WORK_WEEK,
END_WORK_WEEK,
MONTH_NUMBER,
MONTH_NAME,
MONTH_SHORT,
CALENDAR_QUARTER,
CALENDAR_QUARTER_NAME,
CALENDAR_QUARTER_YEAR,
FISCAL_QUARTER,
FISCAL_QUARTER_NAME,
FISCAL_QUARTER_YEAR,
CALENDAR_YEAR_NUMBER,
CALENDAR_YEAR,
FISCAL_YEAR_NUMBER,
FISCAL_YEAR,
IS_HOLIDAY,
IS_BUSINESS_DAY
)
VALUES
(
DATE_KEY_FX(P_DATE), --DATE_KEY
DATE_TYPE_FX(P_DATE), --DATE_TYPE
P_DATE, --FULL_DATE
FULL_DATE_REVERSE_FX(P_DATE), --FULL_DATE_REVERSE
FULL_DATE_DESCRIPTION_FX(P_DATE), --FULL_DATE_DESCRIPTION
DAY_NUMBER_FX(P_DATE), --DAY_NUMBER
DAY_NAME_FX(P_DATE), --DAY_NAME
DAY_SHORT_FX(P_DATE), --DAY_SHORT
DAY_IN_MONTH_FX(P_DATE, 0, 0), --FIRST_DAY_IN_MONTH
DAY_IN_MONTH_FX(P_DATE, 1, 0), --LAST_DAY_IN_MONTH
DAY_IN_MONTH_FX(P_DATE, 0, -1), --FIRST_DAY_IN_PREVIOUS_MONTH
DAY_IN_MONTH_FX(P_DATE, 1, -1), --LAST_DAY_IN_PREVIOUS_MONTH
DAY_IN_MONTH_FX(P_DATE, 0, 1), --FIRST_DAY_IN_NEXT_MONTH
DAY_IN_MONTH_FX(P_DATE, 1, 1), --LAST_DAY_IN_NEXT_MONTH
DAY_IN_QTR_FX(P_DATE, 0, 0, 0), --FIRST_DAY_IN_CALENDAR_QTR
DAY_IN_QTR_FX(P_DATE, 1, 0, 0), --LAST_DAY_IN_CALENDAR_QTR
DAY_IN_QTR_FX(P_DATE, 0, -1, 0), --FIRST_DAY_IN_PREV_CALENDAR_QTR
DAY_IN_QTR_FX(P_DATE, 1, -1, 0), --LAST_DAY_IN_PREV_CALENDAR_QTR
DAY_IN_QTR_FX(P_DATE, 0, 1, 0), --FIRST_DAY_IN_NEXT_CALENDAR_QTR
DAY_IN_QTR_FX(P_DATE, 1, 1, 0), --LAST_DAY_IN_NEXT_CALENDAR_QTR
DAY_IN_YEAR_FX(P_DATE, 0, 0), --FIRST_DAY_IN_CALENDAR_YEAR
DAY_IN_YEAR_FX(P_DATE, 1, 0), --LAST_DAY_IN_CALENDAR_YEAR
DAY_NUMBER_IN_YEAR_FX(P_DATE, 0), --DAY_NUMBER_IN_CALENDAR_YEAR
DAY_IN_QTR_FX(P_DATE, 0, 0, 1), --FIRST_DAY_IN_FISCAL_QTR
DAY_IN_QTR_FX(P_DATE, 1, 0, 1), --LAST_DAY_IN_FISCAL_QTR
DAY_IN_QTR_FX(P_DATE, 0, -1, 1), --FIRST_DAY_IN_PREV_FISCAL_QTR
DAY_IN_QTR_FX(P_DATE, 1, -1, 1), --LAST_DAY_IN_PREV_FISCAL_QTR
DAY_IN_QTR_FX(P_DATE, 0, 1, 1), --FIRST_DAY_IN_NEXT_FISCAL_QTR
DAY_IN_QTR_FX(P_DATE, 1, 1, 1), --LAST_DAY_IN_NEXT_FISCAL_QTR
DAY_IN_YEAR_FX(P_DATE, 0, 1), --FIRST_DAY_IN_FISCAL_YEAR
DAY_IN_YEAR_FX(P_DATE, 1, 1), --LAST_DAY_IN_FISCAL_YEAR
DAY_NUMBER_IN_YEAR_FX(P_DATE, 1), --DAY_NUMBER_IN_FISCAL_YEAR
IS_WEEKDAY_FX(P_DATE), --IS_WEEKDAY
IS_WEEKEND_FX(P_DATE), --IS_WEEKEND
WEEK_IN_MONTH_FX(P_DATE), --WEEK_IN_MONTH
WEEK_IN_YEAR_ISO_FX(P_DATE, 0), --WEEK_IN_CALENDAR_YEAR_ISO
WEEK_IN_YEAR_ISO_FX(P_DATE, 1), --WEEK_IN_FISCAL_YEAR_ISO
WEEK_POINT_FX(P_DATE, 0, 0), --BEGIN_FULL_WEEK
WEEK_POINT_FX(P_DATE, 1, 0), --END_FULL_WEEK
WEEK_POINT_FX(P_DATE, 0, 1), --BEGIN_WORK_WEEK
WEEK_POINT_FX(P_DATE, 1, 1), --END_WORK_WEEK
MONTH_NUMBER_FX(P_DATE), --MONTH_NUMBER
MONTH_NAME_FX(P_DATE), --MONTH_NAME
MONTH_SHORT_FX(P_DATE), --MONTH_SHORT
QUARTER_FX(P_DATE, 0), --CALENDAR_QUARTER
QUARTER_NAME_FX(P_DATE, 0), --CALENDAR_QUARTER_NAME
QUARTER_YEAR_FX(P_DATE, 0), --CALENDAR_QUARTER_YEAR
QUARTER_FX(P_DATE, 1), --FISCAL_QUARTER
QUARTER_NAME_FX(P_DATE, 1), --FISCAL_QUARTER_NAME
QUARTER_YEAR_FX(P_DATE, 1), --FISCAL_QUARTER_YEAR
YEAR_NUMBER_FX(P_DATE, 0), --CALENDAR_YEAR_NUMBER
YEAR_FORMAT_FX(P_DATE, 0), --CALENDAR_YEAR
YEAR_NUMBER_FX(P_DATE, 1), --FISCAL_YEAR_NUMBER
YEAR_FORMAT_FX(P_DATE, 1), --FISCAL_YEAR
IS_HOLIDAY_FX(P_DATE), --IS_HOLIDAY
IS_BUSINESS_DAY_FX(P_DATE) --IS_BUSINESSDAY
);
END NEW_DATE;
我不确定是否需要在存储过程中放置EXECUTE IMMEDIATE
,INSERT INTO
但NEW_DATE
这样做对我当前的问题没有任何影响。
另外,我不是 DBA,所以我确信我的代码有一百万个问题。但是,如果有一种方法可以解决错误并让代码工作,同时仍然使用底层技术(一个存储过程调用另一个调用一堆函数的存储过程),那么这就是我最终要实现的一些协助。
更新 #1
似乎将INSERT INTO
语句封装NEW_DATE
在动态 SQL 中的过程中有所帮助。但是,它引入了以下新错误:
- ORA-00984: 此处不允许列
- ORA-06512: 在“ADMIN.NEW_DATE”,第 5 行
- ORA-06512: 在第 6 行
这些新错误是否可能是由于我在程序部分中使用P_DATE
参数引起的?如果是这样,我将如何更改它以允许使用该参数?我尝试了以下方法,但收到了相同的错误消息(关注 FULL_DATE 列):VALUES
NEW_DATE
EXECUTE IMMEDIATE
'INSERT INTO
(
DATE_TYPE,
FULL_DATE,
FULL_DATE_REVERSE
)
VALUES
(
DATE_TYPE_FX(P_DATE), --DATE_TYPE
'|| P_DATE ||', --FULL_DATE
FULL_DATE_REVERSE_FX(P_DATE) --FULL_DATE_REVERSE
)';
谢谢