我需要编写一个游标,用于显示员工列表,选择mit参数从from_employee和to_employee两个例外。首先需要在没有选择行时工作,而另一个选择只有一行时需要工作。我的代码只是阻止sqldeveloper的所有时间,它开始神经紧张。我需要帮助!!!
`set serveroutput on;
set echo on;
CREATE OR REPLACE PROCEDURE output_employee_set (
from_employee IN NUMBER,
to_employee IN NUMBER,
ascending_order IN BOOLEAN)
IS
v_id EMP.EMPLOYEE_ID%TYPE;
v_ename EMP.FIRST_NAME%TYPE;
v_surname EMP.LAST_NAME%TYPE;
v_email EMP.EMAIL%TYPE;
v_telefon EMP.PHONE_NUMBER%TYPE;
v_hiredate EMP.HIRE_DATE%TYPE;
v_sal EMP.SALARY%TYPE;
v_job JOBS.JOB_TITLE%TYPE;
v_dname DEPARTMENTS.DEPARTMENT_NAME%TYPE;
v_manager EMP.LAST_NAME%TYPE;
one_element Exception;
no_element Exception;
counter NUMBER;
CURSOR emp_cur IS
SELECT e.EMPLOYEE_ID,e.FIRST_NAME,e.LAST_NAME,e.EMAIL,e.PHONE_NUMBER,e.HIRE_DATE,e.SALARY,j.JOB_TITLE,d.DEPARTMENT_NAME,m.LAST_NAME
FROM emp e LEFT OUTER JOIN employees m ON (m.employee_id = e.manager_id), DEPARTMENTS d, JOBS j
WHERE
e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND e.JOB_ID=j.JOB_ID
ORDER BY e.EMPLOYEE_ID ;
BEGIN
SELECT COUNT(e.employee_id) INTO counter FROM emp e LEFT OUTER JOIN employees m ON (m.employee_id = e.manager_id), DEPARTMENTS d, JOBS j
WHERE
e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND e.JOB_ID=j.JOB_ID
ORDER BY e.EMPLOYEE_ID ;
IF ascending_order THEN
OPEN emp_cur;
LOOP
IF v_id BETWEEN from_employee AND to_employee THEN
FETCH emp_cur INTO v_id,v_ename,v_surname,v_email,v_telefon,v_hiredate,v_sal,v_job,v_dname,v_manager;
IF emp_cur%NOTFOUND THEN RAISE no_element;
EXIT;
ELSE
FETCH emp_cur INTO v_id,v_ename,v_surname,v_email,v_telefon,v_hiredate,v_sal,v_job,v_dname,v_manager;
IF counter=1 THEN RAISE one_element;
ELSE
DBMS_OUTPUT.PUT_LINE('Number : ' || v_id);
DBMS_OUTPUT.PUT_LINE('Name : ' || v_ename||' '||v_surname);
DBMS_OUTPUT.PUT_LINE('Email : ' || v_email);
DBMS_OUTPUT.PUT_LINE('Telefon NR. : ' || v_telefon);
DBMS_OUTPUT.PUT_LINE('Eingestellt am : ' || v_hiredate);
DBMS_OUTPUT.PUT_LINE('Gehalt : ' || v_sal);
DBMS_OUTPUT.PUT_LINE('Beruf ID : ' || v_job);
DBMS_OUTPUT.PUT_LINE('Department : ' || v_dname);
DBMS_OUTPUT.PUT_LINE('Vorgesetzter : ' || v_manager);
END IF;
END IF;
END IF;
END LOOP;
CLOSE emp_cur;
END IF;
EXCEPTION
WHEN one_element THEN
DBMS_OUTPUT.PUT_LINE('Just one employee was selected');
WHEN no_element THEN
DBMS_OUTPUT.PUT_LINE('No employees were selected');
END;
/
`
答案 0 :(得分:0)
您的代码中存在少量小错误。
第一个错误:(m.employee_id = e.manager_id)
- 它应该是:(e.employee_id = m.manager_id)
。
第二个错误:定义光标时,必须使用manager last_name
的别名,因为您首先选择employer's last name
,并且会有两行称为LAST_NAME
。
第三个错误:您在该LOOP中没有初始化v_id
。
因此,您必须输入循环,在employee_ID
中获取v_id
,然后检查v_id
和from_employee
之间是否to_employee
。
我使用FOR LOOP重写了你的代码来从光标中获取并且它工作正常。
以下是代码:
CREATE OR REPLACE PROCEDURE output_employee_set (
from_employee IN NUMBER,
to_employee IN NUMBER,
ascending_order IN BOOLEAN)
IS
v_id EMP.EMPLOYEE_ID%TYPE;
v_ename EMP.FIRST_NAME%TYPE;
v_surname EMP.LAST_NAME%TYPE;
v_email EMP.EMAIL%TYPE;
v_telefon EMP.PHONE_NUMBER%TYPE;
v_hiredate EMP.HIRE_DATE%TYPE;
v_sal EMP.SALARY%TYPE;
v_job JOBS.JOB_TITLE%TYPE;
v_dname DEPARTMENTS.DEPARTMENT_NAME%TYPE;
v_manager EMP.LAST_NAME%TYPE;
one_element Exception;
no_element Exception;
counter NUMBER;
CURSOR emp_cur IS
SELECT e.EMPLOYEE_ID, e.FIRST_NAME,
e.LAST_NAME, e.EMAIL,
e.PHONE_NUMBER, e.HIRE_DATE,
e.SALARY, j.JOB_TITLE, d.DEPARTMENT_NAME, m.LAST_NAME as manager_name
FROM emp e LEFT OUTER JOIN employees m ON (e.employee_id = m.manager_id), DEPARTMENTS d, JOBS j
WHERE
e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND e.JOB_ID=j.JOB_ID
ORDER BY e.EMPLOYEE_ID ;
BEGIN
SELECT COUNT(e.employee_id) INTO counter FROM emp e LEFT OUTER JOIN employees m ON (e.employee_id = m.manager_id), DEPARTMENTS d, JOBS j
WHERE
e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND e.JOB_ID = j.JOB_ID
ORDER BY e.EMPLOYEE_ID ;
--Updated
IF (counter = 0 ) THEN
RAISE no_element;
END IF;
IF ascending_order = true THEN
FOR index_cursor IN emp_cur LOOP
v_id := index_cursor.employee_id;
IF (v_id >= from_employee AND v_id <= to_employee) THEN
v_ename := index_cursor.first_name;
v_surname := index_cursor.last_name;
v_email := index_cursor.email;
v_telefon := index_cursor.phone_number;
v_hiredate := index_cursor.hire_date;
v_sal := index_cursor.salary;
v_job := index_cursor.job_title;
v_dname := index_cursor.department_name;
v_manager := index_cursor.manager_name;
-- Or you can directly print the content using
-- DBMS_OUTPUT.PUT_LINE('Number :' || index_cursor.employee_id);
DBMS_OUTPUT.PUT_LINE('Number : ' || v_id);
DBMS_OUTPUT.PUT_LINE('Name : ' || v_ename||' '||v_surname);
DBMS_OUTPUT.PUT_LINE('Email : ' || v_email);
DBMS_OUTPUT.PUT_LINE('Telefon NR. : ' || v_telefon);
DBMS_OUTPUT.PUT_LINE('Eingestellt am : ' || v_hiredate);
DBMS_OUTPUT.PUT_LINE('Gehalt : ' || v_sal);
DBMS_OUTPUT.PUT_LINE('Beruf ID : ' || v_job);
DBMS_OUTPUT.PUT_LINE('Department : ' || v_dname);
DBMS_OUTPUT.PUT_LINE('Vorgesetzter : ' || v_manager);
DBMS_OUTPUT.PUT_LINE('');
--Update
IF (counter = 1 ) THEN
EXIT;
END IF;
END IF;
END LOOP;
IF (counter = 1) THEN
RAISE one_element;
END IF;
END IF;
EXCEPTION
WHEN one_element THEN
DBMS_OUTPUT.PUT_LINE('Just one employee was selected');
WHEN no_element THEN
DBMS_OUTPUT.PUT_LINE('No employees were selected');
END;
/
答案 1 :(得分:0)
为什么不在计算&#39;计数器&#39;的查询中插入条件EMPLOYEE_ID?并形成&#39; emp_cur&#39;分别? 对我来说是这样的(代码基于@PianoSong的变体):
PROCEDURE output_employee_set (
from_employee IN NUMBER,
to_employee IN NUMBER,
ascending_order IN BOOLEAN)
IS
v_id EMP.EMPLOYEE_ID%TYPE;
v_ename EMP.FIRST_NAME%TYPE;
v_surname EMP.LAST_NAME%TYPE;
v_email EMP.EMAIL%TYPE;
v_telefon EMP.PHONE_NUMBER%TYPE;
v_hiredate EMP.HIRE_DATE%TYPE;
v_sal EMP.SALARY%TYPE;
v_job JOBS.JOB_TITLE%TYPE;
v_dname DEPARTMENTS.DEPARTMENT_NAME%TYPE;
v_manager EMP.LAST_NAME%TYPE;
one_element Exception;
no_element Exception;
counter NUMBER;
CURSOR emp_cur IS
SELECT e.EMPLOYEE_ID, e.FIRST_NAME,
e.LAST_NAME, e.EMAIL,
e.PHONE_NUMBER, e.HIRE_DATE,
e.SALARY, j.JOB_TITLE, d.DEPARTMENT_NAME, m.LAST_NAME as manager_name
FROM emp e LEFT OUTER JOIN employees m ON (e.employee_id = m.manager_id), DEPARTMENTS d, JOBS j
WHERE
e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND e.JOB_ID=j.JOB_ID
AND e.EMPLOYEE_ID>=from_employee
AND e.EMPLOYEE_ID<=to_employee
ORDER BY e.EMPLOYEE_ID ;
BEGIN
SELECT COUNT(e.employee_id) INTO counter FROM emp e LEFT OUTER JOIN employees m ON (e.employee_id = m.manager_id), DEPARTMENTS d, JOBS j
WHERE
e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND e.JOB_ID = j.JOB_ID
AND e.EMPLOYEE_ID>=from_employee
AND e.EMPLOYEE_ID<=to_employee
ORDER BY e.EMPLOYEE_ID ;
IF ascending_order = true THEN
IF (counter = 0 ) THEN
RAISE no_element;
ELSIF (counter = 1 ) THEN
RAISE one_element;
END IF;
FOR index_cursor IN emp_cur LOOP
v_ename := index_cursor.first_name;
v_surname := index_cursor.last_name;
v_email := index_cursor.email;
v_telefon := index_cursor.phone_number;
v_hiredate := index_cursor.hire_date;
v_sal := index_cursor.salary;
v_job := index_cursor.job_title;
v_dname := index_cursor.department_name;
v_manager := index_cursor.manager_name;
DBMS_OUTPUT.PUT_LINE('Number : ' || v_id);
DBMS_OUTPUT.PUT_LINE('Name : ' || v_ename||' '||v_surname);
DBMS_OUTPUT.PUT_LINE('Email : ' || v_email);
DBMS_OUTPUT.PUT_LINE('Telefon NR. : ' || v_telefon);
DBMS_OUTPUT.PUT_LINE('Eingestellt am : ' || v_hiredate);
DBMS_OUTPUT.PUT_LINE('Gehalt : ' || v_sal);
DBMS_OUTPUT.PUT_LINE('Beruf ID : ' || v_job);
DBMS_OUTPUT.PUT_LINE('Department : ' || v_dname);
DBMS_OUTPUT.PUT_LINE('Vorgesetzter : ' || v_manager);
DBMS_OUTPUT.PUT_LINE('');
END LOOP;
END IF;
EXCEPTION
WHEN one_element THEN
DBMS_OUTPUT.PUT_LINE('Just one employee was selected');
WHEN no_element THEN
DBMS_OUTPUT.PUT_LINE('No employees were selected');
END;
答案 2 :(得分:0)
set serveroutput on;
set echo on;
CREATE OR REPLACE PROCEDURE output_employee_set (
from_employee IN NUMBER,
to_employee IN NUMBER,
ascending_order IN BOOLEAN)
IS
v_id EMP.EMPLOYEE_ID%TYPE;
v_ename EMP.FIRST_NAME%TYPE;
v_surname EMP.LAST_NAME%TYPE;
v_email EMP.EMAIL%TYPE;
v_telefon EMP.PHONE_NUMBER%TYPE;
v_hiredate EMP.HIRE_DATE%TYPE;
v_sal EMP.SALARY%TYPE;
v_job JOBS.JOB_TITLE%TYPE;
v_dname DEPARTMENTS.DEPARTMENT_NAME%TYPE;
v_manager EMP.LAST_NAME%TYPE;
one_element Exception;
no_element Exception;
counter NUMBER;
CURSOR emp_cur IS
SELECT e.EMPLOYEE_ID,e.FIRST_NAME,e.LAST_NAME,e.EMAIL,e.PHONE_NUMBER,e.HIRE_DATE,e.SALARY,j.JOB_TITLE,d.DEPARTMENT_NAME,m.LAST_NAME
FROM emp e, emp m, DEPARTMENTS d, JOBS j
WHERE
e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND e.MANAGER_ID=m.EMPLOYEE_ID
AND e.JOB_ID=j.JOB_ID
ORDER BY e.EMPLOYEE_ID ;
CURSOR emp_cur_desc IS
SELECT e.EMPLOYEE_ID,e.FIRST_NAME,e.LAST_NAME,e.EMAIL,e.PHONE_NUMBER,e.HIRE_DATE,e.SALARY,j.JOB_TITLE,d.DEPARTMENT_NAME,m.LAST_NAME
FROM emp e, emp m, DEPARTMENTS d, JOBS j
WHERE
e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND e.MANAGER_ID=m.EMPLOYEE_ID
AND e.JOB_ID=j.JOB_ID
ORDER BY e.EMPLOYEE_ID DESC;
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
--counter
SELECT COUNT(*) INTO counter
FROM emp
WHERE employee_id
BETWEEN from_employee AND to_employee;
--Exceptions
IF (counter = 0 ) THEN
RAISE no_element;
END IF;
IF (counter = 1) THEN
RAISE one_element;
END IF;
IF ascending_order THEN
OPEN emp_cur;
LOOP
FETCH emp_cur INTO v_id,v_ename,v_surname,v_email,v_telefon,v_hiredate,v_sal,v_job,v_dname,v_manager;
EXIT WHEN emp_cur%NOTFOUND;
IF v_id BETWEEN from_employee AND to_employee THEN
DBMS_OUTPUT.PUT_LINE('Number : ' || v_id);
DBMS_OUTPUT.PUT_LINE('Name : ' || v_ename||' '||v_surname);
DBMS_OUTPUT.PUT_LINE('Email : ' || v_email);
DBMS_OUTPUT.PUT_LINE('Telefon NR. : ' || v_telefon);
DBMS_OUTPUT.PUT_LINE('Eingestellt am : ' || v_hiredate);
DBMS_OUTPUT.PUT_LINE('Gehalt : ' || v_sal);
DBMS_OUTPUT.PUT_LINE('Beruf ID : ' || v_job);
DBMS_OUTPUT.PUT_LINE('Department : ' || v_dname);
DBMS_OUTPUT.PUT_LINE('Vorgesetzter : ' || v_manager);
END IF;
END LOOP;
CLOSE emp_cur;
END IF;
IF NOT ascending_order THEN
OPEN emp_cur_desc;
LOOP
FETCH emp_cur_desc INTO v_id,v_ename,v_surname,v_email,v_telefon,v_hiredate,v_sal,v_job,v_dname,v_manager;
EXIT WHEN emp_cur_desc%NOTFOUND;
IF v_id BETWEEN from_employee AND to_employee THEN
DBMS_OUTPUT.PUT_LINE('Number : ' || v_id);
DBMS_OUTPUT.PUT_LINE('Name : ' || v_ename||' '||v_surname);
DBMS_OUTPUT.PUT_LINE('Email : ' || v_email);
DBMS_OUTPUT.PUT_LINE('Telefon NR. : ' || v_telefon);
DBMS_OUTPUT.PUT_LINE('Eingestellt am : ' || v_hiredate);
DBMS_OUTPUT.PUT_LINE('Gehalt : ' || v_sal);
DBMS_OUTPUT.PUT_LINE('Beruf ID : ' || v_job);
DBMS_OUTPUT.PUT_LINE('Department : ' || v_dname);
DBMS_OUTPUT.PUT_LINE('Vorgesetzter : ' || v_manager);
END IF;
END LOOP;
CLOSE emp_cur_desc;
END IF;
EXCEPTION
WHEN one_element THEN
DBMS_OUTPUT.PUT_LINE('Just one employee was selected');
WHEN no_element THEN
DBMS_OUTPUT.PUT_LINE('No employees were selected');
END;
/
EXECUTE output_employee_set(208,209,FALSE);