2013-10-04 67 views
0

以下程序符合細,Oracle存儲過程不工作

CREATE PROCEDURE PROCEDURE1 
      (v_MGR int, 
      v_empid IN OUT int) 
    AS 
    BEGIN 
    v_empid :=0; 
    IF (v_mgr IS NOT NULL AND v_mgr <> '') then 
    EXECUTE IMMEDIATE 'SELECT EMPNO 
      FROM EMP 
     WHERE MGR = Rtrim(v_MGR)' into v_empid; 
    END IF; 
    END PROCEDURE1; 

但是當我運行

DECLARE 
    V_MGR NUMBER; 
    V_EMPID NUMBER; 
BEGIN 
    V_MGR := 7902; 
    V_EMPID := NULL; 

    PROCEDURE1(
    V_MGR => V_MGR, 
    V_EMPID => V_EMPID 
); 
    DBMS_OUTPUT.PUT_LINE('V_EMPID = ' || V_EMPID); 
END; 

輸出應v_empid = 2356

但其始終表示v_empid = 0請幫忙得到正確答案

回答

5
  1. 爲什麼out參數是0?您可以在程序

    IF (v_mgr IS NOT NULL AND v_mgr <> '') 
    

    特別是在它的第二部分AND v_mgr <> ''看看if條件。甲骨文對待空字符串爲''null任何比較null導致未知的結果,因此,上述IF條件計算結果始終爲false,以便execute immediate語句根本不會執行和結果的v_empid 值永遠不會被覆蓋。

  2. 在這種特殊情況下,絕對不需要使用動態SQL(本地動態sql execute immediate),因爲沒有動態構建查詢 - 表和列在編譯時是已知的。您可以簡單地使用靜態SQL代替:

  3. 如果您的查詢返回多個行,您將會遇到too_many_rows異常。通過在查詢的where子句中包含rownum=1(如果存在多行返回的更改),或者使用集合作爲參數out來返回結果集,則可以保證查詢返回恰好一行:

    create or replace type T_EmpNums is table of number; 
    /
    
    create or replace procedure procedure1(
        v_mgr int, 
        v_emps out T_empnums 
    ) 
    as 
    begin 
        if v_mgr is not null 
        then 
        select empno 
         bulk collect into v_emps 
         from emp 
         where mgr = v_mgr; 
        end if; 
    end; 
    /
    
    declare 
        v_mgr number; 
        v_empids T_EmpNums; 
    begin 
        v_mgr := 7902; 
        procedure1(v_mgr, v_empids); 
        if v_empids is not empty 
        then 
        for empno in v_empids.first .. v_empids.last 
        loop 
         dbms_output.put_line('v_empid = ' || to_char(v_empids(empno))); 
        end loop; 
        end if; 
    end; 
    
+0

@itmitică'A = null'條件將永遠不會被評估無論爲true空字符串是否已經被分配給了''變量或沒有。不要將它與PL/SQL中直接比較兩個空字符串('''=''')的條件評估爲真的情況混淆。 –

+0

我同意。我的觀點是'a = null'與'a是null'不一樣。這是一個sqlfiddle:http://sqlfiddle.com/#!4/bbbc6/1 – itmitica

1

那麼,你聲明v_MGR int然後你去測試這個v_mgr <> ''並在你的情況下使用這個Rtrim(v_MGR)

這是什麼,(VAR)字符或編號爲mgr和v_mgr?

0

試試這個

CREATE PROCEDURE PROCEDURE1 
     (v_MGR int, 
     v_empid IN OUT int) 
AS 
BEGIN 
v_empid :=0; 
IF (v_mgr IS NOT NULL AND v_mgr <> '') then 
SELECT EMPNO into v_empid 
     FROM EMP 
    WHERE MGR = Rtrim(v_MGR) ; 
END IF; 
END PROCEDURE1;