如何将SQL语句的结果保存到变量中?

时间:2019-09-23 12:25:23

标签: oracle stored-procedures plsql oracle11g

我在Oracle的DB 12.2上。

我想编写一个过程,该过程将截断一个表,然后将输出结果保存到另一个表中,所以类似这样:

CREATE OR REPLACE PROCEDURE truncate_my_table_and_save_result
IS
  variable_output varchar;
BEGIN
     TRUNCATE TABLE EMPLOYEES;
     variable_output := SQL%RESULT;
     insert into log_table (result_column) VALUES (variable_output);

   end;
/

当然是variable_output:= SQL%RESULT;不是有效的语法代码,那我应该怎么用呢?

更新:这里的要点是,我真的想捕捉一个错误,如果它发生在TRUNCATE处(例如,ORA-00054资源NOWAIT)。

1 个答案:

答案 0 :(得分:1)

SQL或PL / SQL中没有成功标志。如果未成功,则会引发异常。

因此,您可以执行此操作(显然取决于要记录的实际文本)。...

CREATE OR REPLACE PROCEDURE truncate_my_table_and_save_result
IS
  variable_output varchar;
BEGIN

    -- Note we cannot write DDL in PL/SQL. Hence the dynamic SQL.
     execute immediate 'TRUNCATE TABLE EMPLOYEES';

     insert into log_table (result_column) VALUES ('Success!');

exception

  when others then
    /* I really want to catch an error if it occurs at TRUNCATE 
     (ORA-00054 resource NOWAIT for example) */
    insert into log_table (result_column) VALUES (SQLERRM);

end;
/

说实话,我认为这种流程代表了不良做法。它吞没了异常,因此调用程序无法知道该语句失败。但是,如果引发异常,则插入将回滚,因此我们需要提交插入:

    …
exception
  when others then
    insert into log_table (result_column) VALUES (SQLERRM);
    commit;
    raise;

end;
/

但这是一个很大的笨拙。更一般而言,尽管调用日志程序的程序发生了什么,但我们希望退出日志消息继续存在,但又不干扰实际事务。

因此,可接受的最小日志记录实现为:

create or replace procedure log_message (p_message_text in varchar2) is
    pragma autonomous_transaction:
begin
    insert into log_table (result_column) values (p_message_text);
    commit;
end log_message;
/

但是实际上,您应该考虑下载Tyler Muth's Logger,它是最接近Oracle标准日志记录软件包的