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 <> '')
    

    特に 2 番目の部分でAND v_mgr <> ''。Oracle は空の文字列''を として扱いnull、比較するnullと不明な結果になるため、上記のIF条件は常に false と評価されるため、execute immediateステートメントは実行されず、結果として の値はv_empid 上書きされません。

  2. この特定の状況では、クエリの動的な構築がないため、動的SQL(ネイティブ動的SQL execute immediate)を使用する必要はまったくありません-テーブルと列はコンパイル時に認識されます。代わりに静的 sql を使用できます。

  3. クエリが複数の行を返す場合、too_many_rows例外が発生します。rownum=1結果セットを返すには、クエリの句に含めることによって (複数の行を返すという変更がある場合)、クエリが正確に 1 つの行を返すことを保証するか、パラメーターwhereとしてコレクションを使用する必要があります。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 または number はどちらですか?

于 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 に答える