如何从替换过程(PL/SQL)中获取旧代码?

Posted

技术标签:

【中文标题】如何从替换过程(PL/SQL)中获取旧代码?【英文标题】:How to get old code from replaced procedure (PL/SQL)? 【发布时间】:2018-11-21 22:12:19 【问题描述】:

我有一个程序一直有效,直到我错误地被其他代码替换。 所以我的程序从CREATE OR REPLACE PROCEDURE xxx.yyy开始,我错误地用一些简单的代码替换并保存了它。

由于我在我的程序中进行了更换,所以它被更换了,但现在它不再按我想要的方式工作了。如何获取该过程中的旧代码(替换前)?

【问题讨论】:

备份或从版本控制(Git/SVN)获取代码(如果有的话)。 嗨@Lukasz,我没有,但它在我的架构下想知道是否还有其他方法?? 好吧,我猜您没有启用任何 DDL 审核或系统级触发器来捕获 DDL 更改。我建议搜索备份或尝试在不同的环境(如 QA/DEV/... 所以教导是:对你的代码使用源代码控制。 【参考方案1】:

当您在xxx 架构上连接时,请尝试使用:

select s.text 
  from user_source 
  as of timestamp systimestamp - interval '1' day s
 where s.name = 'YYY';

获取程序的源代码。它为您提供前一天的数据。您可以根据需要将'1' day 转换为'10' hour'150' minute .. 等,前提是您的db_flashback_retention_target 数据库参数已设置得足够大。

【讨论】:

【参考方案2】:

如果有搜索期间的存档日志。您可以使用实用程序 LogMiner。 例如:

   CREATE OR REPLACE PACKAGE BODY acs_ss2.rest_of_day is

    /*------------------------------------------------------------------*/
    procedure starting(p_date date) is
      rec_newrest   r_rest%rowtype;
      rec_oldrest   r_rest%rowtype;
      rec_rest      r_rest%rowtype;
      v_station   integer := 8902;
      v_dt1 date;
      v_dt2 date;
    begin
SQL CODE...

在事件发生时确定所需的日志文件。

select name, first_time,  next_time
  from v$archived_log
where first_time >sysdate -3/24

/oracle/app/oracle/product/11.2/redolog/edcu/1_47429_769799469.dbf  22-ноя-2018 10:56:12    22-ноя-2018 12:13:48
/oracle/app/oracle/product/11.2/redolog/edcu/1_47430_769799469.dbf  22-ноя-2018 12:13:48    22-ноя-2018 13:17:06
/oracle/app/oracle/product/11.2/redolog/edcu/1_47431_769799469.dbf  22-ноя-2018 13:17:06    22-ноя-2018 13:39:38

运行 logminer 实用程序。

EXECUTE DBMS_LOGMNR.add_logfile(LOGFILENAME => '/oracle/app/oracle/product/11.2/redolog/edcu/1_47429_769799469.dbf', OPTIONS => DBMS_LOGMNR.NEW); 
EXECUTE DBMS_LOGMNR.add_logfile(LOGFILENAME => '/oracle/app/oracle/product/11.2/redolog/edcu/1_47430_769799469.dbf', OPTIONS => DBMS_LOGMNR.addfile); 
EXECUTE DBMS_LOGMNR.add_logfile(LOGFILENAME => '/oracle/app/oracle/product/11.2/redolog/edcu/1_47431_769799469.dbf', OPTIONS => DBMS_LOGMNR.addfile); 

EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);

运行 SQL 以恢复我们的 CODE,请参见 sql_undo 列。

SELECT 
to_char(timestamp,'DD-MM-YYYY HH24:MI:SS'),
operation,  
sql_redo,
sql_undo
 FROM v$logmnr_contents
where 
seg_owner='SYS' and  
seg_name='SOURCE$'
==>
TO_CHAR(TIMESTAMP,'DD-MM-YYYYHH24:MI:SS')       OPERATION                              SQL_REDO                                                                                             SQL_UNDO                                                                                             
----------------------------------------------- -------------------------------------- ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- 
22-11-2018 13:39:14                             DELETE                                 delete from "SYS"."SOURCE$" where "OBJ#" = '197353' and "LINE" = '1' and "SOURCE" = 'package body re insert into "SYS"."SOURCE$"("OBJ#","LINE","SOURCE") values ('197353','1','package body rest_of_day i 
22-11-2018 13:39:14                             DELETE                                 delete from "SYS"."SOURCE$" where "OBJ#" = '197353' and "LINE" = '2' and "SOURCE" = '
' and ROWID =  insert into "SYS"."SOURCE$"("OBJ#","LINE","SOURCE") values ('197353','2','
');                       
22-11-2018 13:39:14                             DELETE                                 delete from "SYS"."SOURCE$" where "OBJ#" = '197353' and "LINE" = '3' and "SOURCE" = '/*------------- insert into "SYS"."SOURCE$"("OBJ#","LINE","SOURCE") values ('197353','3','/*------------------------ 
22-11-2018 13:39:14                             DELETE                                 delete from "SYS"."SOURCE$" where "OBJ#" = '197353' and "LINE" = '4' and "SOURCE" = 'procedure start insert into "SYS"."SOURCE$"("OBJ#","LINE","SOURCE") values ('197353','4','procedure starting(p_date  
22-11-2018 13:39:14                             DELETE                                 delete from "SYS"."SOURCE$" where "OBJ#" = '197353' and "LINE" = '5' and "SOURCE" = '  rec_newrest r insert into "SYS"."SOURCE$"("OBJ#","LINE","SOURCE") values ('197353','5','  rec_newrest r_rest%rowty 

【讨论】:

以上是关于如何从替换过程(PL/SQL)中获取旧代码?的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL:如何在异常中获取 ORA 代码?

如何使用 pl sql 过程从结构仅在运行时知道的 oracle 表中动态获取数据?

PL/SQL 存储过程创建表

创建 pl/sql 过程以从不同的表中获取不同的列

确定 PL/SQL 过程的调用层次结构

带有参数的 PL/SQL 过程/函数从选择查询返回表