PL / SQL - 如何检查是否正在使用包/过程/函数?

时间:2015-04-02 17:09:18

标签: oracle plsql plsqldeveloper

对于看到这个的人,你好。 首先,我对PL / SQL的了解对外行人来说非常基础。我可以阅读代码,进行查询并使用PL / SQL Developer进行研究。这就是我需要做的全部。

我需要知道的是,是否正在使用包/程序/功能和/或上次使用它。有没有办法通过PL / SQL Developer的查询或功能来查看它?

旁注:我已经发现了这个问题,但它并不适合我的需要/没有完全理解那些可能有用的芒果: How can you tell if a PL/SQL Package, Procedure, or Function is being used?

3 个答案:

答案 0 :(得分:2)

您可以在homespun和使用Oracle的内置工具之间进行选择。

对于这种类型的统计数据,我遇到的最可靠和最容易接近的方式是通过简单的NOLOGGING INSERT登录到合适的表中的自制程序代码。不要费心去尝试复杂的求和,因为这会增加开销,只需要一个简单的INSERT,然后根据需要使用报告端进行汇总。您也可以添加时间戳和基本会话信息。

我所看到的另一种我非常喜欢的新方法是,他们创建了一个与每个感兴趣的程序相对应的序列,并在每个程序开始时简单地选择了NEXTVAL。这不会给你基于历史/时间的统计数据;你会把它添加到报告方面,你需要了解CACHE对序列的影响。

就个人而言,我喜欢看到某种代码登录,因为它有助于支持/调试问题,提供对生产系统生命周期的真实洞察。这些信息可以推动改进。

说了这么多,Oracle确实保留了丰富的统计数据,但提取和解释可能是深奥的。如果您可以访问OEM / Grid COntrol(或者他们现在所谓的基于Web的管理控制台),您可以查看时间范围之间的统计信息,并深入查看各个语句和过程。但是,在你知道要寻找什么以及如何获得它之前,这需要一些练习和技巧。

您可以尝试专门针对感兴趣的过程滚动自己的查询。您将从V $ SQL开始获取语句的SQL_ID,然后将其链接到DBA_HIST_SQLSTAT,后者维护统计信息的快照历史记录,包括自上次快照以来的总执行次数和执行次数。

如果您搜索DBA_HIST_SQLSTAT并执行我相信您很快就会找到一个查询来帮助您入门。如果您不是DBA,则需要被授予访问这些视图的权限。

答案 1 :(得分:1)

你无法100%确定

  • 您可以看到上次编译程序包/过程。
  • 你可以看到其他对象依赖它
  • 您可以搜索引用它的动态sql的打包代码,因为它不会显示在依赖项中
  • 除非您查看报告,否则无法判断报告是否调用该对象
  • 除非您在脚本中搜索
  • ,否则您无法判断外部脚本是否会调用它
  • 你无法判断对象是否被外部程序调用

答案 2 :(得分:0)

如果您想要的是它的使用次数(从某个任意重置时间开始)和上次使用的日期,请创建几个私有包变量。

package body package_name as
    F1_Use_Count integer := 0;
    F1_Last_Used timestamp;
    ...
    function F1 ...
        F1_Use_Count := F1_Use_Count + 1;
        F1_Last_Used := SysTimestamp;
        ... the rest of the function
     end F1;

     -- You also want to add
     function Get_F1_Use_Count return integer is begin
         return F1_Use_Count;
     end;
     function Get_F1_Last_Used return timestamp is begin
         return F1_Last_Used;
     end
     proc Reset_F1_Stats is begin
         F1_Use_Count := 0;
         F1_Last_Used := null;
     end;

     -- Or all three above could be done with
     proc Get_Reset_F1_Stats( Use_count out integer, Use_Date out timestamp ) is begin
         Use_count := F1_Use_Count;
         Use_Date := F1_Last_Used;
         F1_Use_Count := 0;
         F1_Last_Used := null;
      end;
end package_name;

修改 到"会话证明"操作,将值写入表而不是包变量。

CREATE TABLE Access_Stats(
    Proc_Id         VARCHAR2( 32 ) NOT NULL, 
    Access_Count    INTEGER DEFAULT 0 NOT NULL,
    Access_Date     DATE DEFAULT SYSDATE NOT NULL, 
    CONSTRAINT PK_TEST PRIMARY KEY( Proc_Id )
);

在包体内:

Proc Set_Stats( PName Access_Stats.Proc_Id%type ) is begin
    MERGE INTO Access_Stats a
    USING(
        SELECT 1 FROM dual ) tt
    ON( a.Proc_Id  = Upper( PName ))
    WHEN MATCHED THEN
        UPDATE
            SET access_count  = access_count + 1,
                access_date   = SYSDATE
    WHEN NOT MATCHED THEN
        INSERT( Proc_Id, access_count )
        VALUES( Upper( PName ), 1 );

    Commit;
END;

然后在您要跟踪的所有函数和过程中,只需确保它们以调用Set_Stats proc开始:

Proc WhatEver...
    Set_Stats( 'whatever' );
...

还必须将getter更改为从表中读取。我会将Get_Reset_F1_Stats proc更改为更通用的Get_Reset_Stats版本:

 proc Get_Reset_Stats(
             PName Access_Stats.Proc_Id%type,
             Use_count out integer,
             Use_Date out timestamp )
 is begin
     Select  Access_Count, Access_Date
         into Use_count, Use_Date
     From    Access_Stats
     where   Proc_Id = Upper( PName );
     update  Access_Stats
         set Access_Count = 0
     where   Proc_Id = Upper( PName );
 end;

Get_Reset_Stats可以删除被跟踪过程的行,但是通过将计数重置为零,可以保持重置日期。如果添加其他字段,例如执行proc的用户,也可以维护上次执行(或重置)被跟踪的过程/功能的人员。

我的标准警告适用:上面显示的代码更多是为了说明而设计的,并不是生产就绪代码。修改以适合您自己的特定标准。