【问题标题】:How to properly call a PL/SQL function with dynamic SQL in it?如何正确调用包含动态 SQL 的 PL/SQL 函数?
【发布时间】:2020-08-13 08:07:34
【问题描述】:

我写了一个 PL/SQL 函数:-

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;
/

但是,我不知道怎么称呼它?在选择查询中调用不起作用,因为该函数具有 DML 和 DDL 语句。

使用以下方式调用:-

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

显示以下错误:-

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

调用和函数都在同一个工作表中执行,并且作为 ADMIN.. 然而,它表明该过程是未定义的。请帮忙。使用Oracle Cloud的SQL Developer Web。

【问题讨论】:

    标签: sql oracle plsql dynamic-sql


    【解决方案1】:

    您的函数返回一个数字。在 pl/sql 块中调用它,在其中将函数分配给 number 类型的变量。下面的例子是一个匿名的 pl/sql 块,但你也可以把它放在函数过程中。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-16
      • 2019-07-10
      • 1970-01-01
      • 2020-06-02
      • 1970-01-01
      • 1970-01-01
      • 2021-06-25
      • 1970-01-01
      相关资源
      最近更新 更多