我想写一个函数,它返回员工工作的部门名称,并使用该函数打印员工名字和部门名称。我得到的错误是" 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;
答案 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;
/