2016-04-14 28 views
2

我終於破解了。下面是我們學校的分配:從程序PLSQL中檢索用戶定義的記錄

添加另一個程序的college_package稱爲get_class_infor。 get_class_infor過程用於獲取並返回類 id,教師姓名,課程名稱和部門的特定 類。將CLASS_ID作爲IN參數傳遞。爲過程中的記錄變量定義用戶定義的記錄 TYPE。

創建一個匿名塊來調用get_class_infor過程並顯示 有關類的信息。下面的示例使用類ID 01.

** Class id:  1 
** Instructor: Gunther Haas 
** Course Title: Algebra I 
** Department: Mathematics 

我創造了這個匿名塊,以確保我明白如何發送參數和檢索用戶定義的記錄。這工作非常好。

匿名塊:

DECLARE 
    TYPE class_type IS RECORD (
    class_id classes.class_id%TYPE, 
    i_first instructors.first_name%TYPE, 
    i_last instructors.last_name%TYPE, 
    course courses.title%TYPE, 
    dept  sections.title%TYPE 
    ); 
    p_rec class_type; 
    PROCEDURE get_class_infor(
     p_id IN NUMBER, 
     p_rec OUT class_type 
    ) IS 
    BEGIN 
     SELECT cl.class_id, i.first_name, i.last_name, cr.title, s.title 
     INTO p_rec 
     FROM classes cl 
     JOIN instructors i ON cl.instr_id = i.instructor_id 
     JOIN courses cr ON cl.course_id = cr.course_id 
     JOIN sections s ON cr.section_code = s.section_code 
     WHERE class_id = p_id; 
    END get_class_infor; 
BEGIN 
    get_class_infor(:class_id, p_rec); 
    DBMS_OUTPUT.PUT_LINE('** Class id:  ' || p_rec.class_id); 
    DBMS_OUTPUT.PUT_LINE('** Instructor: ' || p_rec.i_first || ' ' || p_rec.i_last); 
    DBMS_OUTPUT.PUT_LINE('** Course Title: ' || p_rec.course); 
    DBMS_OUTPUT.PUT_LINE('** Department: ' || p_rec.dept); 
END; 

如果我堅持正確創建封裝規格/機身,還是讓我承擔。我不知道我錯過了什麼。這是我得到的。

包裝規格:

-- Example 4_2A 
CREATE OR REPLACE PACKAGE college_package IS 
    TYPE class_type IS RECORD (
    class_id classes.class_id%TYPE, 
    i_first instructors.first_name%TYPE, 
    i_last instructors.last_name%TYPE, 
    course courses.title%TYPE, 
    dept  sections.title%TYPE 
); 
    PROCEDURE get_class_infor (
    p_id IN NUMBER, 
    p_rec OUT class_type 
); 
END college_package; 

PACKAGE BODY:

-- Example 4_2B 
CREATE OR REPLACE PACKAGE BODY college_package IS 
    PROCEDURE get_class_infor (
    p_id IN NUMBER, 
    p_rec OUT class_type 
) IS 
    BEGIN 
    SELECT cl.class_id, i.first_name, i.last_name, cr.title, s.title 
    INTO p_rec 
    FROM classes cl 
     JOIN instructors i ON cl.instr_id = i.instructor_id 
     JOIN courses cr  ON cl.course_id = cr.course_id 
     JOIN sections s  ON cr.section_code = s.section_code 
     WHERE class_id = p_id; 
    END; 
END college_package; 

匿名塊:

-- Example 4_2C 
DECLARE 
    TYPE class_type IS RECORD (
    class_id classes.class_id%TYPE, 
    i_first instructors.first_name%TYPE, 
    i_last instructors.last_name%TYPE, 
    course courses.title%TYPE, 
    dept  sections.title%TYPE 
); 
    v_rec class_type; 
BEGIN 
    college_package.get_class_infor(:class_id, v_rec); 
    DBMS_OUTPUT.PUT_LINE('** Class id:  ' || v_rec.class_id); 
    DBMS_OUTPUT.PUT_LINE('** Instructor: ' || v_rec.i_first || ' ' || v_rec.i_last); 
    DBMS_OUTPUT.PUT_LINE('** Course Title: ' || v_rec.course); 
    DBMS_OUTPUT.PUT_LINE('** Department: ' || v_rec.dept); 
END; 

急診室ROR消息我得到的是:

ORA-06550:第12行,第4列:
PLS-00306:錯號碼或呼叫 'GET_CLASS_INFOR'
ORA-06550類型的參數:行12,列4:
PL/SQL:語句被忽略

是不是有什麼毛病我怎麼創建包投機/身體?我想自己找到答案,所以向正確的方向暗示將不勝感激。

回答

3

您已經在包規範中定義了一個記錄類型。這意味着您可以在其他程序中使用它,就像您可以調用該過程一樣。

但是你所做的是在你的匿名塊中聲明第二種記錄類型。他們看起來和你一樣,因爲他們有相同的名字和結構。但對編譯器來說,它們是不同的,因爲它們是不同的東西。該過程需要包中定義的記錄類型。

所以解決方法是相當簡單:

DECLARE 
    v_rec college_package.class_type; 
BEGIN 
    college_package.get_class_infor(:class_id, v_rec); 
    DBMS_OUTPUT.PUT_LINE('** Class id:  ' || v_rec.class_id); 
    DBMS_OUTPUT.PUT_LINE('** Instructor: ' || v_rec.i_first || ' ' || v_rec.i_last); 
    DBMS_OUTPUT.PUT_LINE('** Course Title: ' || v_rec.course); 
    DBMS_OUTPUT.PUT_LINE('** Department: ' || v_rec.dept); 
END; 
+0

我剛死一點點... 9小時後,它是如此簡單..哈哈。我試過,但我得到'標識符'CLASS_TYPE'必須聲明'錯誤。我在聲明中的'class_type'之前缺少'college_package'。非常感謝!! – Bryner

+1

@Bryner - 不用擔心:範圍規則很微妙,可以讓任何人都感受到。在光明的一面,這是名稱空間的重要性的一個教訓,它將會使你站得住腳。 – APC