在函数中使用游标输出名称更改

时间:2016-08-03 08:10:38

标签: plsql oracle11g

我正在尝试使用游标按员工姓氏更改

来执行以下操作

创建一个PLSQL函数,当在SQL语句中使用时,它将根据以下逻辑输出employees表中所有雇员的姓氏:

  • 如果员工姓名为KING,则该功能应输出为 狮子。
  • 如果员工的姓名是FORD,则该功能应该是 输出为CAR
  • 如果员工的姓名是MILLER,那么 功能应该改为BEER。

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

到目前为止,我已经拥有了这个:

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; 

我不确定我是否正确使用光标来解决这个问题

2 个答案:

答案 0 :(得分: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个空格,我从不使用大写)。

答案 1 :(得分: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;