2016-11-04 30 views
2

繼續在兩個代碼上獲取相同的錯誤!錯誤:PL/SQL:編譯單元分析終止?

DROP TABLE Date_Dimension CASCADE CONSTRAINTS ; 

CREATE TABLE Date_Dimension 
    (
    date_key    NUMBER NOT NULL , 
    full_date   DATE , 
    day_of_week   NUMBER , 
    day_num_in_month  NUMBER , 
    day_num_overall  NUMBER , 
    day_name    VARCHAR2 (9) , 
    day_abbrev   VARCHAR2 (3) , 
    week_num_in_year  NUMBER , 
    week_num_overall  NUMBER , 
    week_begin_date  DATE , 
    MONTH    NUMBER , 
    month_number_overall NUMBER , 
    month_name   VARCHAR2 (9) , 
    month_abbrev   VARCHAR2 (3) , 
    quarter    NUMBER , 
    YEAR     VARCHAR2 (20) , 
    century    NUMBER 
) ; 
ALTER TABLE Date_Dimension ADD CONSTRAINT Date_Dimension_PK PRIMARY KEY (date_key) ; 

Create or replace PROCEDURE sp_DATE_DIMENSION(v_STARTDATE IN INT, v_END_YEAR IN INT) IS 

v_STARTDATE DATE; 
v_ENDDATE DATE; 

v_STARTDATE Date := to_date('2005/01/01' || v_START_YEAR, 'YYYY/MM/DD'); 
v_ENDDATE Date := to_date('2020/12/31' || v_END_YEAR,'YYYY/MM/DD'); 

BEGIN 

INSERT INTO 

    Date_Dimension 
    (date_key,full_date, day_of_week, day_num_in_month, day_num_overall, day_name, day_abbrev, week_num_in_year, week_num_overall, month, month_name, month_abbrev, quarter, year, century) 

VALUES 
    (
'1',TO_DATE(v_STARTDATE, 'yyyy/mm/dd'), TO_NUMBER(v_STARTDATE, 'D'), TO_NUMBER(v_STARTDATE, 'DD'), TO_NUMBER(v_STARTDATE, 'DDD'), TO_CHAR(v_STARTDATE, 'DAY'), TO_CHAR(v_STARDATE, 'DY'), TO_NUMBER(v_STARTDATE, 'IW'), TO_NUMBER(v_STARTDATE, 'WW'), TO_NUMBER(v_STARTDATE, 'MM'), TO_CHAR (v_STARTDATE, 'MONTH'), TO_CHAR (v_STARTDATE, 'MON'), TO_NUMBER (v_STARTDATE, 'Q'), TO_CHAR (v_STARTDATE, 'YEAR'), TO_NUMBER (v_STARTDATE, 'CC') 
) 
; 

IF v_STARTDATE > v_ENDDATE THEN 

    DBMS_OUTPUT.PUT_LINE ('ERROR IN CODE REGARDING DATES CHOSEN'); 

ELSE 

    WHILE v_STARTDATE <= V_ENDDATE LOOP 
     DBMS_OUTPUT.PUT_LINE ('Date : '||to_char(v_StartDate,'YYYY/MM/DD')); 

     v_STARTDATE := v_STARTDATE + 1; 

    END LOOP; 
END IF; 
END; 
+1

什麼是錯誤和哪裏它出現了嗎? – Dmitry

+0

你正在使用哪個客戶端?應該有一些方法來查看除初始終止消息之外的實際錯誤 - 可能位於IDE的另一個窗口或部分中;或者通過諸如SQL \ * Plus「'show錯誤「;或者通過查詢'user_errors'作爲一個回退,它保存了所有存儲的PL/SQL代碼的所有未解決的錯誤,如果你能看到一個你應該能夠看到其他錯誤...... –

+0

Oracle SQL Developer返回錯誤消息,不允許我確切地查看錯誤的位置 – Coder101

回答

1

你的代碼獲取

PLS-00410: duplicate fields in RECORD,TABLE or argument list are not permitted

您已經從程序的格式參數列表複製名稱startdate作爲一個局部變量;然後再重複兩次。我認爲你的意思只是一年的正式觀點,因爲它是一個數字。您的轉換日期也是錯誤的:

to_date('2005/01/01' || v_START_YEAR, 'YYYY/MM/DD') 

...沒有意義,因爲您已經有2005年硬編碼。

我認爲這部分你想要的東西更像是:與調整,以匹配其他變量的引用

create or replace PROCEDURE sp_DATE_DIMENSION(p_START_YEAR IN NUMBER, p_END_YEAR IN NUMBER) IS 
    l_START_DATE Date := to_date(p_START_YEAR ||'-01-01', 'YYYY-MM-DD'); 
    l_END_DATE Date := to_date(p_END_YEAR ||'-01-01', 'YYYY-MM-DD'); 
BEGIN 

。在插入時,您將第一個值作爲字符串'1'而不是數字1傳遞。然後您對已經過期的變量調用to_date();並且您可以使用日期元素的格式掩碼調用to_number() - 用於需要轉換爲字符串的數字,然後再轉換爲數字。這樣插入woudl變得更像:

INSERT INTO Date_Dimension (date_key, full_date, day_of_week, day_num_in_month, 
    day_num_overall, day_name, day_abbrev, week_num_in_year, week_num_overall, 
    month, month_name, month_abbrev, quarter, year, century) 
    VALUES (1, 
    l_START_DATE, 
    TO_NUMBER(TO_CHAR(l_START_DATE, 'D')), 
    TO_NUMBER(TO_CHAR(l_START_DATE, 'DD')), 
    TO_NUMBER(TO_CHAR(l_START_DATE, 'DDD')), 
    TO_CHAR(l_START_DATE, 'DAY'), 
    TO_CHAR(l_START_DATE, 'DY'), 
    TO_NUMBER(TO_CHAR(l_START_DATE, 'IW')), 
    TO_NUMBER(TO_CHAR(l_START_DATE, 'WW')), 
    TO_NUMBER(TO_CHAR(l_START_DATE, 'MM')), 
    TO_CHAR(l_START_DATE, 'MONTH'), 
    TO_CHAR(l_START_DATE, 'MON'), 
    TO_NUMBER(TO_CHAR(l_START_DATE, 'Q')), 
    TO_CHAR (l_START_DATE, 'YEAR'), 
    TO_NUMBER(TO_CHAR(l_START_DATE, 'CC')) 
); 

這是不使用dbms_output錯誤消息,爲(a)調用程序沒有其他跡象表明,什麼是錯的良好做法,以及(b)甚至在一個簡單的客戶端調用用戶可能甚至沒有捕獲或顯示啓用的那些。這是更好地拋出一個異常:

IF l_START_DATE > l_END_DATE THEN 
    RAISE_APPLICATION_ERROR (-20001, 'ERROR IN CODE REGARDING DATES CHOSEN'); 
    END IF; 

    WHILE l_START_DATE <= l_END_DATE LOOP 
    DBMS_OUTPUT.PUT_LINE ('Date : ' || to_char(l_START_DATE, 'YYYY/MM/DD')); 
    l_START_DATE := l_START_DATE + 1; 
    END LOOP; 
END; 
/

異常會導致程序提前終止,因此超出了達到無論如何,如果日期是錯誤的,你不需要else一部分罷了。即使如此,你可能真的想在循環中做插入操作,以便創建所有相關的行;在一開始就做檢查和例外處理是有意義的(也許比較幾年而不是日期,但並不重要,而且可能我已經忘記了其他的東西 - 希望這會讓你更加接近正確的軌道你並不真的需要一個過程,甚至是PL/SQL,因爲它可以用普通的SQL和單個插入來完成,但希望這是一個練習。