2016-08-03 24 views
0

我努力做到以下几点使用光标按雇员姓氏在输出名称的功能使用光标改变

改变创建PLSQL功能,这在SQL语句将输出的姓氏使用时在雇员表中的所有员工按照以下逻辑:

  • 如果该员工的姓名为王,函数应该输出为 狮子。
  • 如果雇员的名字是福特,功能应该 输出为CAR
  • 如果雇员的名字是MILLER,那么 功能应将其更改为啤酒。

否则,该名称应按雇员表中列出的名称输出。

到目前为止,我有这个:

set serveroutput on; 
CREATE OR REPLACE FUNCTION changeName (lastname_in IN VARHCAR2) 

    RETURN c_emp_record 
    IS 
declare 

CURSOR c_emp_record IS 
    SELECT last_name FROM employees; 
    v_emp_record c_emp_record%ROWTYPE; 
begin 
OPEN c_emp_record; 
DBMS_OUTPUT.PUT_LINE('LastName'||' '); 
    LOOP 
    FETCH c_emp_record into v_emp_record; 
     EXIT WHEN c_emp_record%NOTFOUND; 
     if c_emp_record IN ('%KING%') THEN 
     DBMS_OUTPUT.PUT_LINE(' LION'); 
     elsif c_emp_record LIKE '%FORD%' THEN  
     DBMS_OUTPUT.PUT_LINE(' CAR'); 
     ELSIF c_emp_record LIKE '%MILLER%' THEN  
     DBMS_OUTPUT.PUT_LINE('BEER'); 
     ELSE 
     DBMS_OUTPUT.PUT_LINE(v_emp_record.last_name || 'No change'); 
    END IF; 
    END LOOP; 

    end changeName; 

我不知道如果我正确使用光标对于这个问题

回答

0

试试这个。此外,这里也不需要光标。既然你传递了last_name,函数反正会返回一个值。

CREATE OR REPLACE FUNCTION changeName (lastname_in IN VARCHAR2) 
    RETURN varchar2 
IS 

    CURSOR c_emp_record IS 
    SELECT emp_name 
    FROM employee 
    where emp_name = lastname_in ; 

    v_emp_record employee.emp_name%TYPE; 

Begin 
OPEN c_emp_record; 

DBMS_OUTPUT.PUT_LINE('LastName'||' '); 
    LOOP 
    FETCH c_emp_record into v_emp_record; 
     EXIT WHEN c_emp_record%NOTFOUND; 

     if v_emp_record LIKE '%KING%' THEN 
     v_emp_record:='LION'; 
     DBMS_OUTPUT.PUT_LINE(v_emp_record) ; 

     Elsif v_emp_record LIKE '%FORD%' THEN 
     v_emp_record := 'CAR'; 
     DBMS_OUTPUT.PUT_LINE(v_emp_record) ; 

     ELSIF v_emp_record LIKE '%MILLER%' THEN 
     v_emp_record := 'BEER'; 
     DBMS_OUTPUT.PUT_LINE(v_emp_record) ;  

     END IF; 
    END LOOP; 

Close c_emp_record ; 
return (v_emp_record); 

End changeName; 
1

由于分配呼叫为一个函数,据推测,预计此返回一个引用游标,在这种情况下,它可以是沿着线(未测试):

create or replace function newname 
    (lastname_in in employees.name%type) 
    return sys_refcursor 
as 
    c_results sys_refcursor; 
begin 
    open c_results for 
     select first_name 
      , last_name 
      , case last_name 
        when 'KING' then 'LION' 
        when 'FORD' then 'CAR' 
        when 'MILLER' then 'BEER' 
        else last_name 
       end as new_name 
     from employees 
     where last_name = lastname_in 
     order by last_name, first_name; 

    return c_results; 
end newname; 

如果过程是接受和“输出”可能意味着DBMS_OUTPUT(通常是诊断/调试工具,不适合生产报告),你可以尝试像这样(未经):

create or replace procedure newname 
    (lastname_in in employees.name%type) 
as 
begin 
    for r in (
     select last_name 
      , case last_name 
        when 'KING' then 'LION' 
        when 'FORD' then 'CAR' 
        when 'MILLER' then 'BEER' 
        else last_name 
       end as new_name 
     from employees 
     where last_name = lastname_in 
     order by last_name, first_name 
    ) 
    loop 
     dbms_output.put_line(r.new_name); 
    end loop; 

end newname; 

我不知道是什么腠但是我想知道为什么所有的初学者似乎都会使用最复杂的游标构造(声明游标,打开,循环,取出,退出等)。标准的for r in (...) loop构造是大多数情况下你所需要的(这就是说,如果你甚至需要一个循环)并且速度通常更快。

此外,还有一个习惯性的做法,就是一致地使用大写/小写和标准缩进(我使用了4个空格,而且我从不使用大写字母)。