【问题标题】:oracle stored procedure not workingoracle存储过程不工作
【发布时间】:2013-10-05 21:01:25
【问题描述】:

以下程序符合要求,

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

【问题讨论】:

    标签: oracle stored-procedures


    【解决方案1】:
    1. 为什么out参数为0?看看过程中的if条件

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

      尤其是第二部分AND v_mgr &lt;&gt; ''。 Oracle 将空字符串'' 视为null 并且与null 的任何比较都会导致未知结果,因此上述IF 条件总是评估为假,因此execute immediate 语句永远不会执行,因此@987654331 的值@ 永远不会被覆盖。

    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;
      

    【讨论】:

    • @itmiticăa = null 条件永远不会被评估为真,无论是否已将空字符串分配给 a 变量。不要将其与我们在 PL/SQL 中直接比较两个空字符串 (''='') 的条件评估为真这一事实混淆。
    • 我同意。我的观点是a = nulla is null 不同。这是一个 sqlfiddle:sqlfiddle.com/#!4/bbbc6/1
    【解决方案2】:

    好吧,你声明v_MGR int,然后你去测试这个v_mgr &lt;&gt; ''并在你的条件下使用这个Rtrim(v_MGR)

    mgr 和 v_mgr 是 (var)char 还是 number?

    【讨论】:

      【解决方案3】:

      试试这个

      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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-13
        • 2014-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-01
        相关资源
        最近更新 更多