简体   繁体   中英

How to properly call a PL/SQL function with dynamic SQL in it?

I wrote a PL/SQL function:-

CREATE OR REPLACE FUNCTION register_driver1(driver_name IN VARCHAR, pass_word IN VARCHAR) RETURN NUMBER AS
sql_stmt VARCHAR2(200);
driver_id NUMBER;
new_view_name VARCHAR(50);
BEGIN

    sql_stmt := 'CREATE USER '||driver_name||' identified by '||pass_word;

    EXECUTE IMMEDIATE sql_stmt;

    sql_stmt := 'grant create session to '||driver_name;

    EXECUTE IMMEDIATE sql_stmt;

    driver_id := driver_ids.nextval;
    new_view_name := 'vehicle_'||driver_name;

    sql_stmt := 'CREATE VIEW '||new_view_name|| ' AS SELECT Model, Seats, reg_no FROM Vehicle WHERE(d_id='||driver_id||')';

    EXECUTE IMMEDIATE sql_stmt;

    sql_stmt := 'CREATE OR REPLACE TRIGGER reg_vehicle 
                 INSTEAD OF INSERT ON '||new_view_name||
               ' FOR EACH ROW 
                 DECLARE 
                 vehicle_id NUMBER;
                 BEGIN
                 vehicle_id := vehicle_ids.nextval
                 INSERT INTO Vehicles VALUES(:NEW.Model, :NEW.Seats, :NEW.reg_no, vehicle_id, '||driver_id||');
                 END;';

    EXECUTE IMMEDIATE sql_stmt;

    sql_stmt := 'grant insert, update, select, delete on '||new_view_name||' to '||driver_name;  

    EXECUTE IMMEDIATE sql_stmt;

    sql_stmt := 'grant select on PENDING_REQUESTS to '||driver_name;

    EXECUTE IMMEDIATE sql_stmt;

    RETURN driver_id;

END register_driver1;
/

But, I am not able to figure how to call it? Calling within a select query doesn't work because the function has DML and DDL statements.

Calling using the following:-

BEGIN
  register_driver1('RoCK', 'wt893fdg$');
END;
/

shows the following error:-

Function REGISTER_DRIVER1 compiled

Elapsed: 00:00:00.009

ORA-06550: line 2, column 3: PLS-00221: 'REGISTER_DRIVER1' is not a procedure or is undefined ORA-06550: line 2, column 3: PL/SQL: Statement ignored

Both the call and function are executed in same worksheet and as ADMIN.. Yet, it shows that the procedure is undefined. Please help. SQL Developer Web of Oracle Cloud is used.

Your function returns a number. Call it in a pl/sql block where you assign the function to a variable of type number. The example below is a anonymous pl/sql block but you can also put this in a procedure of function.

DECLARE
  l_driver_id NUMBER;
BEGIN
  l_driver_id := register_driver1('RoCK', 'wt893fdg$');
  -- rest of code ... --
END;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM