跨存储过程的Oracle表使用情况

时间:2013-02-11 12:55:22

标签: sql oracle stored-procedures oracle11g

我有一个11G的数据库。我需要检查一些存储过程,看看它们是否使用特定的表。 (前端和后端sps)我可以完全访问数据库,并且还有一个存储在TFS上的项目所有单个sp的副本。

我想要一种方法来生成与此特定表交互的所有sp的列表。我不熟悉如何寻找这些。任何人都可以建议获得这些数据的最合理方式吗?

感谢。

5 个答案:

答案 0 :(得分:14)

如果我理解正确,那么您正试图在所有存储过程中搜索table的出现位置。在这种情况下,您可以使用此查询:

搜索架构中SP的出现次数

SELECT * FROM user_source WHERE text LIKE '%tab_name%';

在所有模式中搜索SP的出现次数

SELECT * FROM all_source WHERE text LIKE '%tab_name%';

答案 1 :(得分:5)

两件事,在PL / SQL中有一些变化需要重新编译pl / sql对象,其他则不需要。 要查看第一个,您可以看到ALL_DEPENDENCIES视图。或DBA_,如果您愿意。

如果您只想查看表名在所有pl / sql代码中的显示位置,那么对表的更改是否需要重新编译,您可以使用ALL_SOURCE使用upper和%,但是可能需要一些时间。

答案 2 :(得分:3)

我使用PLSQL Developer,您可以浏览到表(或其他对象),并查看'Referenced by',以查看引用该表的所有对象。这就像它变得一样简单。 我可以想象其他工具具有类似的功能。

我不知道这个预先解析的信息是否可以在Oracle中获得,但我可以这么想,因为这些工具似乎工作得非常快。

此信息可在All_DEPENDENCIES视图中找到,这些工具可能会使用这些信息。

存储过程的源可以在USER_SOURCE(或ALL_SOURCE)视图中找到,其中存储了整个数据库的结构。然而,从那里获取和解析代码会非常麻烦。

答案 3 :(得分:0)

以下是我为给定的@schema(仅限大写)和@table(仅限大写)执行影响分析(仅限MERGE,INSERT和UPDATE)的片段。它将返回所有过程名称,过程代码,行号和行号以及其他详细信息。它可以很容易地用于包括函数对象而不是包。我正在开发一个可以跨所有架构或选定架构运行的实用程序(也包括SELECT行)。虽然这对你开始工作已经足够好了。

我知道您可以使用Oracle中可用的依赖项和引用来执行类似的操作。但对于包级别的影响,这是一个很好的补充。我们还可以使用正则表达式进行更复杂的搜索。但是就像操作员对我的需求一样简单而有效。

请注意,这不适用于可能在您的环境中运行的任何动态代码。这只是一个适当的起点,可以快速了解包中的静态PL / SQL代码。

WITH TableDep as
-- This table returns references where the table is used within the code for UPDATE OR INSERT
(
SELECT 
owner as schemaname,
name as packagename, 
type as typename,
TEXT as refcodeline,
CASE WHEN upper(text) LIKE '%INSERT%' THEN 'INSERT'
     WHEN upper(text) LIKE '%UPDATE%' THEN 'UPDATE'
   WHEN upper(text) LIKE '%MERGE%' THEN 'MERGE'
END AS opr,
:Tablename AS Tablename,
line refline
FROM dba_source WHERE upper(owner) = upper(:OWNER)  
      AND type = 'PACKAGE BODY' 
      AND (
            upper(text) LIKE ('%INSERT INTO '||:Tablename||'%')
            OR 
            upper(text) LIKE ('%UPDATE%'||:Tablename||' %')
            OR
            upper(text) LIKE ('%MERGE%'||:Tablename||' %')
           )
  ),
ProcedureDetails as
-- This code build all procedures within the package for references that is found in above query
(
SELECT 
  owner as schemaname,
  name as packagename, 
  type as typename,
  TEXT,
  trim(REGEXP_SUBSTR(TEXT, '(PROCEDURE [[:print:]]+)\(',1,1,null,1))   as procedure_name,
  line startline,
  LEAD(line, 1) OVER (partition by name order by line)-1 as endline
FROM dba_source
WHERE owner = upper(:OWNER) 
      AND type = 'PACKAGE BODY' 
      AND upper(text) LIKE '%PROCEDURE%(%'
      and exists (SELECt 1 FROM TableDep WHERE TableDep.packagename=name)
)
,ProcCode as
-- This code builds procedures into one cell per program for a given package. Later to find the  effected procedures
(
SELECT 
       ProcTag.packagename ,
       ProcTag.schemaname,
       ProcTag.typename,
       ProcTag.PROCEDURE_NAME,
       ProcTag.startline,
       ProcTag.endline,
       TO_CLOB(rtrim(xmlagg(xmlelement(e,codeline.text).extract('//text()') order by line).GetClobVal(),',')) as Procedure_Code
FROM
    ProcedureDetails ProcTag
    INNER JOIN dba_source codeline ON ProcTag.packagename=codeline.name
                                      AND ProcTag.schemaname=codeline.owner
                                      and ProcTag.typename=codeline.type
                                      and codeline.line between ProcTag.startline and ProcTag.endline
--WHERE PROCEDURE_NAME='PROCEDURE TRANS_KAT_INSO'
    group by 
       ProcTag.packagename ,
       ProcTag.schemaname,
       ProcTag.typename,
       ProcTag.PROCEDURE_NAME,
       ProcTag.startline,
       ProcTag.endline
      )
-- extract all the reference code for the given table selected with it complete procedure code.
SELECT
ProcHeader.Packagename, ProcHeader.schemaname, ProcHeader.typename, ProcHeader.procedure_name, ProcHeader.Procedure_Code ,ProcHeader.startline,ProcHeader.endline,ProcReference.Tablename, ProcReference.opr
FROM 
  ProcCode ProcHeader
  INNER JOIN 
        (
          SELECT DISTINCT ProcCode.Packagename, ProcCode.schemaname, ProcCode.typename, ProcCode.procedure_name , TableDep.Tablename, TableDep.opr
          FROM               ProcCode 
                  INNER JOIN TableDep ON ProcCode.packagename=TableDep.packagename
                                            AND ProcCode.schemaname=TableDep.schemaname
                                            and ProcCode.typename=TableDep.typename
                                            and TableDep.refline between ProcCode.startline and ProcCode.endline
        ) ProcReference
    ON    ProcHeader.Packagename=ProcReference.Packagename
          AND ProcHeader.schemaname=ProcReference.schemaname
          AND ProcHeader.typename=ProcReference.typename
          AND ProcHeader.procedure_name=ProcReference.procedure_name
;

答案 4 :(得分:0)

此问题已经有一个可接受的答案,但是无论如何,在接受的答案中使用的query将选择所有使用特定表的user sources

由于问题是关于Procedures的特定问题,您可以通过以下查询获取结果

SELECT * FROM user_source WHERE text LIKE '%YourTableName%' and TYPE='PROCEDURE';