PL-SQL: выполнить триггер внутри процедуры - PullRequest
0 голосов
/ 17 июня 2019

Я хочу выполнить триггер внутри процедуры.Есть ли способ выполнить PL / SQL (с apices) внутри процедуры?Я пытаюсь с этим кодом получить следующую ошибку.

 LINE/COL ERROR
 -------- -----------------------------------------------------------------
 6/22     PLS-00103: Encountered the symbol "
          CREATE OR REPLACE TRIGGER managed_service_start
          AFTER STARTUP ON DATABASE
          DECLARE
          pdb_role VARCHAR2(64);
          pdb_name " when expecting one of the following:
          ( - + case mod new not null <an identifier>
          <a double-quoted delimited-identifier> <a bind variable>
          continue avg count current exists max min prior sql stddev
          sum variance execute forall merge time timestamp interval
          date <a string literal with character set specification>

 LINE/COL ERROR
 -------- -----------------------------------------------------------------
          <a number> <a s

Как мне поступить?Моя цель - запустить эту процедуру всего один раз и избежать выполнения триггера внутри каждого pdb.

CREATE OR REPLACE PROCEDURE start_services AS
BEGIN
    FOR i IN (SELECT name FROM v$pdbs p WHERE p.name <> 'PDB$SEED')
    LOOP
        EXECUTE IMMEDIATE 'ALTER SESSION SET CONTAINER= ' || i.name;
        EXECUTE IMMEDIATE  '
        CREATE OR REPLACE TRIGGER managed_service_start
            AFTER STARTUP ON DATABASE
        DECLARE
            pdb_role VARCHAR2(64);
            pdb_name VARCHAR2(64);
            host VARCHAR2(64);
        BEGIN
            SELECT database_role INTO pdb_role FROM v$database;
            SELECT Upper(sys_context ("userenv", "con_name")) INTO pdb_name FROM dual;
            SELECT host_name INTO host FROM v$instance;

            IF pdb_role = "PRIMARY" THEN
                DBMS_SERVICE.START_SERVICE(pdb_name || "_RW");
            ELSE
                -- IF host IN ("host_name1","host_name2") THEN
                IF host LIKE "%de%" THEN 
                    DBMS_SERVICE.START_SERVICE(pdb_name || "_RO");
                END IF;
            END IF;
        END;
        /
        ';
    END LOOP;
END;
/

Ответы [ 2 ]

1 голос
/ 17 июня 2019

В вашем тексте похоже, что вы помещаете двойные кавычки вокруг всех своих литералов.Это должны быть одинарные кавычки.

Поскольку эти одинарные кавычки находятся внутри буквенной строки, вам нужно поместить две одинарные кавычки в ряд.

begin
execute immediate '
CREATE OR REPLACE TRIGGER managed_service_start
AFTER STARTUP ON DATABASE
DECLARE
  pdb_role VARCHAR2(64);
  pdb_name VARCHAR2(64);
  host VARCHAR2(64);
BEGIN
  SELECT database_role INTO pdb_role FROM v$database;
  SELECT Upper(sys_context (''userenv'', ''con_name'')) INTO pdb_name FROM dual;
  SELECT host_name INTO host FROM v$instance;

  IF pdb_role = ''PRIMARY'' THEN
    DBMS_SERVICE.START_SERVICE(pdb_name || ''_RW'');
  ELSE
    -- IF host IN (''host_name1'',''host_name2'') THEN
    IF host LIKE ''%de%'' THEN 
      DBMS_SERVICE.START_SERVICE(pdb_name || ''_RO'');
    END IF;
  END IF;
END;
/';
end;
/

С уважением, Стью Эштон

0 голосов
/ 17 июня 2019

Проще, замените все двойные кавычки одинарными кавычками и оберните DDL триггера строкой в ​​кавычках (q'<delimeter><Your code><delimeter>') следующим образом:

CREATE OR REPLACE PROCEDURE start_services AS
BEGIN
    FOR i IN (SELECT name FROM v$pdbs p WHERE p.name <> 'PDB$SEED')
    LOOP
        EXECUTE IMMEDIATE 'ALTER SESSION SET CONTAINER= ' || i.name;
        EXECUTE IMMEDIATE  q'#
        CREATE OR REPLACE TRIGGER managed_service_start
            AFTER STARTUP ON DATABASE
        DECLARE
            pdb_role VARCHAR2(64);
            pdb_name VARCHAR2(64);
            host VARCHAR2(64);
        BEGIN
            SELECT database_role INTO pdb_role FROM v$database;
            SELECT Upper(sys_context ('userenv', 'con_name')) INTO pdb_name FROM dual;
            SELECT host_name INTO host FROM v$instance;

            IF pdb_role = 'PRIMARY' THEN
                DBMS_SERVICE.START_SERVICE(pdb_name || '_RW');
            ELSE
                -- IF host IN ('host_name1','host_name2') THEN
                IF host LIKE '%de%' THEN 
                    DBMS_SERVICE.START_SERVICE(pdb_name || '_RO');
                END IF;
            END IF;
        END;
        #';
    END LOOP;
END;
/

Ура !!

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