Как написать процедуру PL / SQL с использованием вместо триггера как Dynami c SQL? - PullRequest
0 голосов
/ 29 апреля 2020

Я написал функцию PL / SQL и использую Dynami c SQL для выполнения оператора триггера Create следующим образом: -

CREATE OR REPLACE FUNCTION register_driver1(driver_name IN VARCHAR, pass_word IN VARCHAR) RETURN NUMBER AS
sql_stmt VARCHAR2(500);
driver_id NUMBER;
new_view_name VARCHAR(50);   --<-----Line 4
BEGIN
--function statements

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;  --<-----Line 32

--Remaining function body
END;
/

Здесь определены переменные new_view_name, driver_id над этим фрагментом кода. Vehicle - это таблица (Model, Seats, Reg_no, vehicel_id, driver_id), а reg_vehicle(Model, Seats, Reg_no) - это представление, имеющее Vehicle с определенного driver_id.

vehicle_ids - последовательность, созданная вне процедуры.

Выше показана ошибка компиляции в строке EXECUTE IMMEDIATE. Как правильно это сделать?

Ошибка, отображаемая при вызове функции с некоторыми имя_драйвера и паролем: -

ORA-24344: success with compilation error ORA-06512: at "ADMIN.REGISTER_DRIVER1", line 32 ORA-06512: at line 4

1 Ответ

0 голосов
/ 29 апреля 2020

Ну, я бы не рекомендовал создавать объекты динамически .

Если вы - по какой-то причине - настаиваете на этом, то другая проблема: вы не можете выполнять DDL здесь, как вы вызовет функцию, например,

select register_driver1(...) from dual;

и получит

ORA-14552: не может выполнить DDL, фиксацию или откат внутри запроса или DML

Итак - переключитесь на процедуру с параметром OUT, чтобы вернуть то, что должна вернуть эта функция.


По ошибке, которую вы получили: вы пропустили BEGIN. Примерно так компилирует :

SQL> CREATE OR REPLACE PROCEDURE register_driver1 (driver_name  IN VARCHAR,
  2                                                pass_word    IN VARCHAR)
  3  AS
  4     sql_stmt       VARCHAR2 (500);
  5     driver_id      NUMBER;
  6     new_view_name  VARCHAR (50);
  7  BEGIN
  8     sql_stmt :=
  9           'CREATE OR REPLACE TRIGGER reg_vehicle
 10                   INSTEAD OF INSERT ON '
 11        || new_view_name
 12        || ' FOR EACH ROW
 13                   DECLARE
 14                   vehicle_id NUMBER;
 15                   BEGIN
 16                   vehicle_id := vehicle_ids.nextval
 17                   INSERT INTO Vehicles VALUES(:NEW.Model, :NEW.Seats, :NEW.reg_no, vehicle_id, '
 18        || driver_id
 19        || ');
 20                   END;';
 21
 22     -- EXECUTE IMMEDIATE sql_stmt;
 23     DBMS_OUTPUT.put_line (sql_stmt);
 24  END;
 25  /

Procedure created.

SQL>
SQL> SET SERVEROUTPUT ON;
SQL> EXEC register_driver1('a', 'b');
CREATE OR REPLACE TRIGGER reg_vehicle
                 INSTEAD OF INSERT ON  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, );

END;

PL/SQL procedure successfully completed.

SQL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...