程序执行 table

Procedure execution table

我有这个程序:

create or replace procedure tst
begin
    execute immediate 'create table tb1 select 1 col from dual';
    execute immediate 'create table tb2 select 1 col from dual';

    insert into tb3 select 1 from dual;

    execute immediate 'truncate table tb3';
    --error table not specified
    execute immediate 'create table tb4 select 1 col from ';
    execute immediate 'truncate table tb4';
end;

我需要创建一个 table 并将过程中执行的所有操作输入其中。类似于此:

"txt"                       "dt"                  "name procedure"
procedure started           20.09.2021 15:12:11   tst
table tb1 created           20.09.2021 15:12:11   tst
table tb2 created           20.09.2021 15:12:12   tst
insert into tb3             20.09.2021 15:12:14   tst
truncate tab3               20.09.2021 15:12:16   tst
error table not specified   20.09.2021 15:12:16   tst

谢谢!

你可以创建这样一个table

CREATE TABLE log_ops( txt VARCHAR2(400), dt DATE, proc_name VARCHAR2(40) );

和具有嵌套过程的过程,以便记录相关步骤,例如

CREATE OR REPLACE PROCEDURE tst AS
  v_ddl VARCHAR2(150);
  v_prc VARCHAR2(40) := $$PLSQL_UNIT;
  PROCEDURE pr_ins(i_txt VARCHAR2) IS
     PRAGMA AUTONOMOUS_TRANSACTION;
   BEGIN
     INSERT INTO log_ops VALUES(i_txt,SYSDATE,v_prc);
     COMMIT;
   END; 
BEGIN
  pr_ins('procedure started');
  v_ddl := 'CREATE TABLE tb1 SELECT 1 col FROM dual';
  EXECUTE IMMEDIATE v_ddl;
  pr_ins('table tb1 created');
  
  v_ddl := 'CREATE TABLE tb2 SELECT 1 col FROM dual';  
  EXECUTE IMMEDIATE v_ddl;
  pr_ins('table tb2 created');

  INSERT INTO tb3 SELECT 1 FROM dual;
  pr_ins('insert into tb3');

  v_ddl := 'TRUNCATE TABLE tb3';  
  EXECUTE IMMEDIATE v_ddl;
  pr_ins('truncate tab3');

  v_ddl := 'CREATE TABLE tb4 SELECT 1 col FROM...';  
  EXECUTE IMMEDIATE v_ddl;
  pr_ins('error table not specified');

  v_ddl := 'TRUNCATE TABLE tb4';  
  EXECUTE IMMEDIATE v_ddl;
  pr_ins('truncate tab4');
 EXCEPTION WHEN others THEN pr_ins('error : '||sqlerrm);  
END;

这是您可以执行此操作的一种方法:

tb3 需要在编译 tst 之前存在,否则过程 tst 永远不会编译。

create table tb3 as select 1 col from dual;
create table tb_log
( id          NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY
, txt VARCHAR2(100)
, proc VARCHAR2(100)
, create_date DATE
);

现在创建一个过程 tst。请注意,每个可能出错的语句都必须放在它们自己的块中,并且需要捕获异常。否则它将在第一个错误后停止执行。

create or replace procedure tst
as
  procedure logit(txt_i tb_log.txt%TYPE)
  IS
  BEGIN
    INSERT INTO tb_log(txt, proc, create_date) 
      VALUES (txt_i, $$plsql_unit, sysdate);
  END logit;
begin
    logit('procedure started');
    BEGIN
      execute immediate 'create table tb1 as select 1 col from dual';
      logit('table tb1 created');
    EXCEPTION WHEN OTHERS THEN
      logit('table tb1 created ERROR: '||SQLERRM);
    END;
    BEGIN
      execute immediate 'create table tb2 as select 1 col from dual';
      logit('table tb2 created');
    EXCEPTION WHEN OTHERS THEN
      logit('table tb2 created ERROR: '||SQLERRM);
    END;
    
    -- this will fail if 
    insert into tb3 select 1 from dual;
    logit('insert into tb3 select 1 from dual');

    execute immediate 'truncate table tb3';
    logit('truncate tb3');
    --error table not specified
    BEGIN
      execute immediate 'execute immediate create table tb4 as select 1 col from';
      logit('table tb4 created');
    EXCEPTION WHEN OTHERS THEN
      logit('table tb4 created ERROR: '||SQLERRM);
    END;    
    BEGIN
      execute immediate 'truncate table tb4';
      logit('truncate table tb4');
    EXCEPTION WHEN OTHERS THEN
      logit('truncate table tb4 ERROR: '||SQLERRM);
    END;      
end;
/

运行 并检查结果:

BEGIN
  tst;
END;
/

select * from tb_log;

1   procedure started   TST 20-SEP-2021
2   table tb1 created   TST 20-SEP-2021
3   table tb2 created   TST 20-SEP-2021
4   insert into tb3 select 1 from dual  TST 20-SEP-2021
5   truncate tb3    TST 20-SEP-2021
6   table tb4 created ERROR: ORA-00900: invalid SQL statement   TST 20-SEP-2021
7   truncate table tb4 ERROR: ORA-00942: table or view does not exist   TST 20-SEP-2021

请注意代码中的语法错误:CREATE TABLE tb1 SELECT 1 col1 FROM DUAL 将引发异常 ORA-00922: missing or invalid option。正确的语法是CREATE TABLE tb1 AS SELECT 1 col1 FROM DUAL(注意关键字AS