Reputation: 307
the below procedure complies fine,
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;
but when i run
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;
the output should be v_empid =2356
but its always showing v_empid = 0 please help to get proper answer
Upvotes: 0
Views: 2537
Reputation: 27251
Why is the out
parameter is 0? Take a look at the if
condition in the procedure
IF (v_mgr IS NOT NULL AND v_mgr <> '')
especially at its second part AND v_mgr <> ''
. Oracle treats empty string ''
as null
and any comparison to null
leads to unknown result, thus the above IF
condition always evaluates to false so execute immediate
statement never executes and as a result the value of v_empid
will never be overwritten.
In this particular situation there is absolutely no need of using dynamic SQL(native dynamic sql execute immediate
), because there is no dynamic construction of the query - table and columns are known at compile-time. You simply could use static sql instead:
If your query returns more than one row, you will hit too_many_rows
exception. You either should guarantee that your query returns exactly one row, by including rownum=1
in the where
clause of the query(if there is a change of returning multiple rows) or you use a collection as the out
parameter, to return the result set:
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;
Upvotes: 5
Reputation: 511
Well, you declare v_MGR int
and then you go and test this v_mgr <> ''
and use this Rtrim(v_MGR)
in your condition.
Which is it, (var)char or number for mgr and v_mgr?
Upvotes: 1
Reputation: 560
try this
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;
Upvotes: 0