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
    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 请帮助获得正确的答案

4

3 回答 3

5
  1. 为什么out参数是0?看看if过程中的条件

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

    特别是在它的第二部分AND v_mgr <> ''。Oracle 将空字符串''视为null任何比较都会null导致未知结果,因此上述IF条件始终评估为 false,因此execute immediate语句永远不会执行,因此v_empid 永远不会覆盖 的值。

  2. 在这种特殊情况下,绝对不需要使用动态 SQL(本机动态 sql execute immediate),因为没有动态构造查询 - 表和列在编译时是已知的。您只需使用静态 sql 代替:

  3. 如果您的查询返回多于一行,您将遇到too_many_rows异常。您应该保证您的查询只返回一行,方法是在查询rownum=1where子句中包含(如果返回多行的更改),或者使用集合作为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;
    
于 2013-10-04T20:47:52.447 回答
1

好吧,你声明v_MGR int然后你去测试它v_mgr <> ''Rtrim(v_MGR)在你的条件下使用它。

哪个是 mgr 和 v_mgr 的 (var)char 或数字?

于 2013-10-04T20:46:19.810 回答
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;
于 2013-10-04T20:48:36.300 回答