Search code examples
sqloracle-databaseplsqlstored-functions

How to execute stored function in Oracle PL/SQL


I want to execute this stored function, and insert data in table t I tried to find solution, but unsuccessfully

CREATE TABLE t (id number
              , name varchar2(32)
              , time date);

CREATE OR REPLACE PACKAGE t_api AS
    FUNCTION func_ins (
        p_row IN t%rowtype
    ) RETURN t.id%TYPE;
END t_api;
/

CREATE OR REPLACE PACKAGE BODY t_api AS
FUNCTION func_ins (
    p_row IN t%rowtype
) RETURN t.id%TYPE 
IS
    l_id t.id%TYPE;
BEGIN
    INSERT INTO t VALUES p_row RETURNING id INTO l_id;    
    RETURN l_id;
END func_ins;
END t_api;
/


declare
p_row t%rowtype;
begin
p_row.id := 1;
p_row.name := 'name';
p_row.time := sysdate;
t_api.func_ins(p_row);
end;
/

I got

PLS-00221

Thanks in advance


Solution

  • It works perfectly ,however i wouldn't recommend this design as its not a good practice to perform a DML within a function. Rather create a procedure instead of function and retrieve the Id using the out parameter.

    Anonymous block to test the function when table is empty.You assign values for %ROWTYPE variable and insert.

      declare 
        t_row t%rowtype;
        x t.id%type;
        begin
    
        t_row.id := 2;
        t_row.name := 'Test2';
        t_row.time := sysdate;
    
         x :=  t_api.func_ins(t_row);
    
         dbms_output.put_line('x '||x);
    
        end;
    

    Output is

     x 2
    

    Modified code with Procedure to achieve the same result is below,

    CREATE OR REPLACE PACKAGE t_api AS
        FUNCTION func_ins (
            p_row IN t%rowtype
        ) RETURN t.id%TYPE;
      PROCEDURE   proc_ins (
        p_row IN t%rowtype,
        l_id out t.id%TYPE
    ); 
    END t_api;
    /
    
    CREATE OR REPLACE PACKAGE BODY t_api AS
    FUNCTION func_ins (
        p_row IN t%rowtype
    ) RETURN t.id%TYPE 
    IS
        l_id t.id%TYPE;
    BEGIN
        INSERT INTO t VALUES p_row RETURNING id INTO l_id;    
        RETURN l_id;
    END func_ins;
    PROCEDURE proc_ins (
        p_row IN t%rowtype,
        l_id out t.id%TYPE
    ) 
    IS
    
    BEGIN
        INSERT INTO t VALUES p_row RETURNING id INTO l_id;    
    
    END proc_ins;
    END t_api;
    /
    

    Anonymous block to test the procedure,

    declare 
    t_row t%rowtype;
    x t.id%type;
    begin
    
    
    t_row.id := 3;
    t_row.name := 'Test3';
    t_row.time := sysdate;
    
     t_api.proc_ins(t_row,x);
     dbms_output.put_line('x '||x);
    
    
    end;
    

    Output is

    x 3