2017-08-25 39 views
1

這些是我所創建的表的列表,並插入值作爲創建的表:編寫一個函數來顯示基於Oracle中特定部門的員工信息?

CREATE TABLE DEPARTMENT 
(DEPARTMENT_ID NUMBER PRIMARY KEY, 
DEPARTMENT_NAME VARCHAR(30) NOT NULL 
); 

CREATE TABLE JOBS 
(JOB_ID NUMBER PRIMARY KEY, 
    JOB_TITLE VARCHAR(35) NOT NULL, 
    MIN_SALARY DECIMAL NOT NULL, 
    MAX_SALARY DECIMAL NOT NULL 
); 

CREATE TABLE EMPLOYEES 
(EMPLOYEE_ID NUMBER PRIMARY KEY, 
FIRST_NAME VARCHAR(20) NOT NULL, 
LAST_NAME VARCHAR(25) NOT NULL, 
EMAIL VARCHAR(25) NOT NULL, 
PHONE_NUMBER VARCHAR(20) NOT NULL, 
HIRE_DATE DATE NOT NULL, 
JOB_ID NUMBER NOT NULL, 
SALARY DECIMAL NOT NULL, 
DEPARTMENT_ID NUMBER NOT NULL, 
CONSTRAINT emp_job_fk FOREIGN KEY(JOB_ID) REFERENCES JOBS(JOB_ID), 
CONSTRAINT emp_department_fk FOREIGN KEY(DEPARTMENT_ID) REFERENCES DEPARTMENT(DEPARTMENT_ID) 
); 

INSERT INTO DEPARTMENT (DEPARTMENT_ID,DEPARTMENT_NAME) 
VALUES(1,'IT'); 
INSERT INTO DEPARTMENT (DEPARTMENT_ID,DEPARTMENT_NAME) 
VALUES(2,'Sales'); 

INSERT INTO JOBS (JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY) 
VALUES (1,'IT Administrator',250000.00,50000.00); 
INSERT INTO JOBS (JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY) 
VALUES (2,'Salesman',200000.00,40000.00); 

INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID) 
VALUES (1,'Tony','Starc','[email protected]','',TO_DATE('15/1/2008','DD/MM/YYYY'),1,45000.00,1); 
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID) 
VALUES (2,'Bruce','Wayne','[email protected]','',TO_DATE('15/1/2009','DD/MM/YYYY'),1,40000.00,1); 
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID) 
VALUES (3,'Larry','Ellison','[email protected]','',TO_DATE('15/1/2010','DD/MM/YYYY'),1,30000.00,1); 
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID) 
VALUES (4,'Steve','Jobs','[email protected]','',TO_DATE('15/1/2011','DD/MM/YYYY'),2,35000.00,2); 
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID) 
VALUES (5,'Remy','Lebeau','[email protected]','',TO_DATE('15/1/2012','DD/MM/YYYY'),2,30000.00,2); 
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID) 
VALUES (6,'Clark','Kent','[email protected]','',TO_DATE('15/1/2013','DD/MM/YYYY'),2,20000.00,2); 

現在在我的任務,我一直要求解決以下問題:

寫調用的函數fn_emps_per_dept_jc450912以檢索具有給定DEPARTMENT_ID的EMPLOYEE_ID,FIRST_NAME,LAST_NAME和JOB_TITLE。此函數應將DEPARTMENT_ID作爲輸入參數,此函數應具有EMPLOYEE_ID,FIRST_NAME,LAST_NAME和JOB_TITLE作爲輸出參數。它應該返回TRUE,如果找到則返回FALSE。

爲了從一個特定部門顯示員工的信息,我寫了下面的功能:

CREATE OR REPLACE FUNCTION fn_emps_per_dept_jc450912 (f_dept_id NUMBER) 
RETURN SYS_REFCURSOR 
AS 
emp_details SYS_REFCURSOR; 
BEGIN 
OPEN emp_details 
FOR 
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,JOB_TITLE 
FROM EMPLOYEES,JOBS,DEPARTMENT 
WHERE DEPARTMENT.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID 
AND JOBS.JOB_ID = EMPLOYEES.JOB_ID 
AND EMPLOYEES.DEPARTMENT_ID = f_dept_id; 
RETURN emp_details; 
EXCEPTION 
WHEN NO_DATA_FOUND 
THEN 
DBMS_OUTPUT.PUT_LINE('Department not available'); 
END fn_emps_per_dept_jc450912; 

VARIABLE e REFCURSOR 
EXECUTE :e := fn_emps_per_dept_jc450912(1); 

PRINT e; 

EMPLOYEE_ID FIRST_NAME   LAST_NAME     JOB_TITLE 
----------- -------------------- ------------------------- ---------------------------- 
      1 Tony     Starc      IT Administrator 
      2 Bruce    Wayne      IT Administrator 
      3 Larry    Ellison     IT Administrator 

然後我試圖插入一個無效的部門編號:

VARIABLE e REFCURSOR 
EXECUTE :e := fn_emps_per_dept_jc450912(5); 

PRINT e; 

我有以下3個問題:

  1. 爲什麼是空白的?可能的錯誤在哪裏?
  2. 問題要求EMPLOYEE_ID,名字,姓氏和JOB_TITLE應該是輸出參數。但是,我要返回EMPLOYEE_ID,FIRST_NAME,LAST_NAME和JOB_TITLE作爲SYS_REFCURSOR。那麼,我的方法是基於問題想要的關於輸出參數的正確方法嗎?
  3. 我需要修復哪部分代碼?這個功能如何重寫?
+0

這是[Tony Stark](http://marvelcinematicuniverse.wikia.com/wiki/Iron_Man)。 –

+1

您不會從引用遊標獲取'no_data_found'異常,只能從'select into'中獲取。在任何情況下,該過程只是將光標傳遞迴調用方,因此無法知道是否將返回任何行。 (這是實際運行查詢的調用者 - 過程只是爲執行做好準備。)順便說一下,不需要用大寫代碼。也許你已經習慣了COBOL。 –

+0

@WilliamRobertson - 另外,託尼斯塔克是不是拉里埃裏森的虛構化? – APC

回答

0

NO_DATA_FOUND將不會在開啓REF CURSOR時提出。所以,你可以使用下面的方法。

  • 將department_id的員工數存儲到變量中。 如果count of employees = 0明確提出NO_DATA_FOUND
  • 在異常塊中,打開另一個遊標,它將返回一個 消息而不是原始列。

下面是修改的功能。

CREATE OR REPLACE FUNCTION fn_emps_per_dept_jc450912(
    f_dept_id NUMBER) 
    RETURN SYS_REFCURSOR 
AS 
    emp_details SYS_REFCURSOR; 
    v_emp_id_count NUMBER; 
BEGIN 
    SELECT COUNT(EMPLOYEES.employee_id) 
    INTO v_emp_id_count 
    FROM EMPLOYEES, 
    JOBS, 
    DEPARTMENT 
    WHERE DEPARTMENT.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID 
    AND JOBS.JOB_ID    = EMPLOYEES.JOB_ID 
    AND EMPLOYEES.DEPARTMENT_ID = f_dept_id; 
    IF v_emp_id_count    = 0 THEN 
    RAISE NO_DATA_FOUND; 
    END IF; 
    OPEN emp_details FOR SELECT EMPLOYEE_ID, 
    FIRST_NAME, 
    LAST_NAME, 
    JOB_TITLE FROM EMPLOYEES, 
    JOBS, 
    DEPARTMENT WHERE DEPARTMENT.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID 
    AND JOBS.JOB_ID = EMPLOYEES.JOB_ID AND EMPLOYEES.DEPARTMENT_ID = f_dept_id; 
    RETURN emp_details; 
EXCEPTION 
WHEN NO_DATA_FOUND THEN 
    OPEN emp_details FOR SELECT 'Department not available' MESSAGE FROM DUAL; 
    RETURN emp_details; 
END fn_emps_per_dept_jc450912; 
/

所以對於第二殼體(dept_id = 5),從PRINT的輸出將是。

MESSAGE     
------------------------ 
Department not available 
相關問題