编写一个函数,返回员工工作的部门名称,并使用该功能打印员工名字和部门名称

时间:2016-06-04 01:03:41

标签: plsql

我想写一个函数,它返回员工工作的部门名称,并使用该函数打印员工名字和部门名称。我得到的错误是" empno必须被声明" 这里是代码:

create or replace function empdnm (empno1 number) return varchar2 is 
 deptname varchar (30);
BEGIN   
 SELECT d.department_name
 INTO   deptname
 FROM   DEPARTMENTS d
 JOIN   EMPLOYEES e on e.DEPARTMENT_ID = d.DEPARTMENT_ID
 WHERE  e.EMPLOYEE_ID = empno;

return(deptname);
 exception
   WHEN no_data_found THEN
    dbms_output.put_line('no employee with no:'|| empno);
end;

BEGIN
   FOR r IN (SELECT * FROM EMPLOYEES) loop
    dbms_output.put_line( 'employee '|| r.FIRST_name  || ' is in department  || empdnm(r.empno) );
END loop;
end;

1 个答案:

答案 0 :(得分:0)

为什么要编写这样的功能,然后为所有员工调用它? 更有效的方法是将这些查询合并为一个:

DECLARE
    -- I prefer using explicitly declared cursors rather than implicit cursors (like SELECT .. INTO ..)
    CURSOR c_emp_dept IS
    SELECT
        e.first_name
        ,d.department_name
    FROM
        departments d
        ,employees e
    WHERE
        d.department_id = e.department_id;
BEGIN
    FOR r IN c_emp_dept
    LOOP
        dbms_output.put_line('Employee '||r.first_name||' is in department '||r.department_name);
    END LOOP;
END;
/

如果由于某种原因你需要创建一个函数(一些学校任务):

-- As IN parameter name for functions or procedures I use 'p_' prefix not to mess up my variables later
-- and to easily find my parameter usage in the function body
CREATE OR REPLACE FUNCTION get_emp_dept_name(p_employee_id IN EMPLOYEES.EMPLOYEE_ID%TYPE)
RETURN VARCHAR2 IS
    CURSOR c_emp_dept IS
    SELECT
        d.department_name
    FROM
        departments d
        ,employees e
    WHERE
        d.department_id = e.department_id
        AND e.employee_id = p_employee_id;

    ls_dept_name        DEPARTMENTS.DEPARTMENT_NAME%TYPE;
BEGIN
    OPEN c_emp_dept;
    FETCH c_emp_dept INTO ls_dept_name;
    CLOSE c_emp_dept;

    -- Declared Cursor doesn't throw NO_DATA_FOUND exception
    IF ls_dept_name IS NULL THEN
        dbms_output.put_line('There is either no employee with id '||p_employee_id||' or the department assignment was created wrongly.');
    END IF;

    -- Returns department name if found, NULL if not found
    RETURN ls_dept_name;

END get_emp_dept_name;
/

DECLARE
    ls_dept_name        DEPARTMENTS.DEPARTMENT_NAME%TYPE;
BEGIN
    -- Here I fetch only the columns that you actually use.
    -- The EMPLOYEES table may contain some huge sized columns (e.g. CLOB) and fetching it without even using it
    -- would only result in occuppying the DB memory
    FOR r IN (SELECT e.employee_id, e.first_name FROM employees e)
    LOOP
        ls_dept_name := GET_EMP_DEPT_NAME(p_employee_id => r.employee_id);
        dbms_output.put_line('Employee '||r.first_name||' is in department '||ls_dept_name);
    END LOOP;
END;
/