2016-08-03 66 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個空格,而且我從不使用大寫字母)。